home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / utility2 / wincmd.zip / WINCMC.ZIP / WINCMD.C < prev    next >
C/C++ Source or Header  |  1993-04-07  |  118KB  |  3,669 lines

  1. //===========================================================
  2. // WINCMD - A command language interpeter for Windows
  3. // Copyright (C) 1993 Douglas Boling
  4. //===========================================================
  5. // Returns no. of elements
  6. #define dim(x) (sizeof(x) / sizeof(x[0]))   
  7.  
  8. #define    VARBUFFSIZE              42000
  9. #define    TOKBUFFSIZE              65500
  10.  
  11. #define    MAXLINELEN               256
  12. #define    MAXSTRLEN                252
  13. #define    MAXOUTLINES              100
  14.  
  15. #define    MAXLIBS                  32
  16. //-----------------------------------------------------------
  17. // Include flags for WINDOWS.H
  18. //-----------------------------------------------------------
  19. #define NOCOMM             1    Comm driver APIs and definitions
  20. #define NOMINMAX           1    min() and max() macros
  21. #define NOLOGERROR         1    LogError() and related definitions
  22. #define NOPROFILER         1    Profiler APIs
  23. #define NORESOURCE         1    Resource management
  24. #define NOATOM             1    Atom management
  25. #define NOLANGUAGE         1    Character test routines
  26. #define NODBCS             1    Double-byte character set routines
  27. #define NOGDICAPMASKS      1    GDI device capability constants
  28. #define NODRAWTEXT         1    DrawText() and related definitions
  29. #define NOTEXTMETRIC       1    TEXTMETRIC and related APIs
  30. #define NOSCALABLEFONT     1    Truetype scalable font support
  31. #define NOBITMAP           1    Bitmap support
  32. #define NORASTEROPS        1    GDI Raster operation definitions
  33. #define NOMETAFILE         1    Metafile support
  34. #define NOSYSTEMPARAMSINFO 1    SystemParametersInfo() and SPI_#define definitions
  35. #define NODEFERWINDOWPOS   1    DeferWindowPos and related definitions
  36. #define NOKEYSTATES        1    MK_* message key state flags
  37. #define NOWH               1    SetWindowsHook and related WH_* definitions
  38. #define NOSCROLL           1    Scrolling APIs and scroll bar control
  39. //#define NOVIRTUALKEYCODES  1    VK_* virtual key codes
  40. //#define NOMENUS            1    Menu APIs
  41. //#define NOKEYBOARDINFO     1    Keyboard driver routines
  42. //#define NOCOLOR            1    COLOR_#define color values
  43. //#define NOGDIOBJ           1    GDI pens, brushes, fonts
  44. //#define NOMSG              1    APIs and definitions that use MSG structure
  45. //#define NOWINSTYLES        1    Window style definitions
  46.  
  47. //-----------------------------------------------------------
  48. // Include files
  49. //-----------------------------------------------------------
  50. #include "windows.h"
  51. #include "commdlg.h"
  52. #include "stdlib.h"
  53. #include "direct.h"
  54. #include "dos.h"
  55. #include "string.h"
  56. #include "WinCmd.h"
  57.  
  58. // Message handler functions
  59. LONG DoCreateMain (HWND, UINT, UINT, LONG);
  60. LONG DoSizeMain (HWND, UINT, UINT, LONG);
  61. LONG DoTimerMain (HWND, UINT, UINT, LONG);
  62. LONG DoInitMenuMain (HWND, UINT, UINT, LONG);
  63. LONG DoDestroyMain (HWND, UINT, UINT, LONG);
  64. LONG DoCommandMain (HWND, UINT, UINT, LONG);
  65. LONG DoRefreshMain (HWND, UINT, UINT, LONG);
  66.  
  67. // Menu Function Prototypes
  68. //LONG DoMainCtlExit (HWND, UINT, HWND, UINT);
  69. LONG DoMainMenuFileOpen (HWND, UINT, HWND, UINT);
  70. LONG DoMainMenuFileLoad (HWND, UINT, HWND, UINT);
  71. LONG DoMainMenuFileExit (HWND, UINT, HWND, UINT);
  72. LONG DoMainMenuShowList (HWND, UINT, HWND, UINT);
  73. LONG DoMainMenuShowOut (HWND, UINT, HWND, UINT);
  74. LONG DoMainMenuClearOut (HWND, UINT, HWND, UINT);
  75. LONG DoMainMenuMinOnRun (HWND, UINT, HWND, UINT);
  76. LONG DoMainMenuAbout (HWND, UINT, HWND, UINT);
  77.  
  78. // Control function Prototypes
  79. LONG DoMainCtlRun (HWND, UINT, HWND, UINT);
  80. LONG DoMainCtlStep (HWND, UINT, HWND, UINT);
  81. LONG DoMainCtlReset (HWND, UINT, HWND, UINT);
  82. // Utility function prototpes
  83. BOOL MyYield (void);
  84. BOOL MyGetFilename (HWND, char *, INT, char *, INT);
  85.  
  86. //------------------------------------------------------------
  87. // Message dispatch table for MainWindowProc
  88. //------------------------------------------------------------
  89. struct decodeUINT MainMessages[] = {
  90.     WM_COMMAND, DoCommandMain,
  91.     WM_CREATE, DoCreateMain,
  92.     WM_SIZE, DoSizeMain,
  93.     WM_TIMER, DoTimerMain,
  94.     WM_INITMENU, DoInitMenuMain,
  95.     MYMSG_REFRESH, DoRefreshMain,
  96.     WM_DESTROY, DoDestroyMain} ;
  97.  
  98. //------------------------------------------------------------
  99. // Command Message dispatch for MainWindowProc
  100. //------------------------------------------------------------
  101. struct decodeCMD MainMenuItems[] = {
  102.     IDD_RUN, DoMainCtlRun,
  103.     IDD_STEP, DoMainCtlStep,
  104.     IDD_RESET, DoMainCtlReset,
  105.     IDM_OPEN, DoMainMenuFileOpen,
  106.     IDM_LOAD, DoMainMenuFileLoad,
  107.     IDM_EXIT, DoMainMenuFileExit,
  108.     IDM_SHOWLIST, DoMainMenuShowList,
  109.     IDM_SHOWOUT, DoMainMenuShowOut,
  110.     IDM_CLEAROUT, DoMainMenuClearOut,
  111.     IDM_MINONRUN, DoMainMenuMinOnRun,
  112.     IDM_ABOUT, DoMainMenuAbout} ;
  113.  
  114. //-----------------------------------------------------------
  115. // Application specific function prototypes
  116. //-----------------------------------------------------------
  117.  
  118. INT InitInterpeter (HWND);
  119. INT ResetInterpeter (HWND);
  120. INT TermInterpeter (void);
  121. INT ParseCmdLine (LPSTR);
  122. void WriteOutput (HWND, char *);
  123. void PrintError (HWND, INT, INT, BOOL);
  124. INT LoadProgram (HWND, HANDLE *, LPLINETOKEN, UINT);
  125. INT TokenizeLine (LPSTR *, LPLINETOKEN *, UINT);
  126. INT AddTokenInit (char *, BYTE, UINT, DWORD);
  127. PTOKEN AddToken (char *, BYTE, UINT, DWORD, INT *);
  128. PTOKEN AddTokenL (LPSTR, BYTE, UINT, DWORD, LPINT);
  129. INT SetToken (PTOKEN, BYTE, UINT, DWORD);
  130. //LPTOKEN CALLBACK AddTokenExt (              LPSTR, BYTE, UINT, DWORD, LPINT);
  131. DWORD CALLBACK TokFuncCallback (INT, LPTOKEN, LPSTR, BYTE, UINT, DWORD);
  132. LONG ComputeNum (LPSTR *, INT *);
  133. INT GetOp (LPLINETOKEN *, PTOKEN, UINT *, INT);
  134. INT Eval (LPLINETOKEN *, PTOKEN, INT);
  135. LONG Eval2Num (LPLINETOKEN *, INT, INT *);
  136. INT ExecuteLine (LPLINETOKEN *, INT);
  137. INT Execute (LPLINETOKEN *, INT);
  138. LONG GetTokenVal (PTOKEN);
  139. LPSTR GetTokenStringL (PTOKEN);
  140. char *GetTokenString (PTOKEN);
  141. INT ResolveLine (LPLINETOKEN *, LPSTR, INT);
  142.  
  143. INT ReadFile (char *, HANDLE *);
  144. INT StuffKeyString (char **);
  145.  
  146. INT LocalOpCPren (LPLINETOKEN *, PTOKEN, PTOKEN);
  147. INT LocalOpAdd (LPLINETOKEN *, PTOKEN, PTOKEN);
  148. INT LocalOpSub (LPLINETOKEN *, PTOKEN, PTOKEN);
  149. INT LocalOpMul (LPLINETOKEN *, PTOKEN, PTOKEN);
  150. INT LocalOpDiv (LPLINETOKEN *, PTOKEN, PTOKEN);
  151. INT LocalOpCmp (LPLINETOKEN *, PTOKEN, PTOKEN);
  152. INT LocalOpNOT (LPLINETOKEN *, PTOKEN, PTOKEN);
  153. INT LocalOpNOTBits (LPLINETOKEN *, PTOKEN, PTOKEN);
  154. INT LocalOpAND (LPLINETOKEN *, PTOKEN, PTOKEN);
  155. INT LocalOpANDBits (LPLINETOKEN *, PTOKEN, PTOKEN);
  156. INT LocalOpOR (LPLINETOKEN *, PTOKEN, PTOKEN);
  157. INT LocalOpORBits (LPLINETOKEN *, PTOKEN, PTOKEN);
  158. INT LocalOpXOR (LPLINETOKEN *, PTOKEN, PTOKEN);
  159. INT LocalOpXORBits (LPLINETOKEN *, PTOKEN, PTOKEN);
  160. INT LocalOpLThan (LPLINETOKEN *, PTOKEN, PTOKEN);
  161. INT LocalOpLEThan (LPLINETOKEN *, PTOKEN, PTOKEN);
  162. INT LocalOpGThan (LPLINETOKEN *, PTOKEN, PTOKEN);
  163. INT LocalOpGEThan (LPLINETOKEN *, PTOKEN, PTOKEN);
  164. INT LocalOpNotEqual (LPLINETOKEN *, PTOKEN, PTOKEN);
  165. INT LocalComma (LPLINETOKEN *, PTOKEN, PTOKEN);
  166.  
  167. INT LocalOpOPren (LPLINETOKEN *, PTOKEN);
  168. INT LocalLENGTH (LPLINETOKEN *, PTOKEN);
  169. INT LocalUPPER (LPLINETOKEN *, PTOKEN);
  170. INT LocalSUBSTR (LPLINETOKEN *, PTOKEN);
  171. INT LocalARG (LPLINETOKEN *, PTOKEN);
  172. INT LocalWAIT (LPLINETOKEN *, PTOKEN);
  173. INT WinActivate (LPLINETOKEN *, PTOKEN);
  174. INT WinSendKeys (LPLINETOKEN *, PTOKEN);
  175. INT WinGetActWin (LPLINETOKEN *, PTOKEN);
  176. INT WinGetNextWin (LPLINETOKEN *, PTOKEN);
  177. INT WinGetWinEXE (LPLINETOKEN *, PTOKEN);
  178. INT WinMsgBox (LPLINETOKEN *, PTOKEN);
  179. INT WinAskBox (LPLINETOKEN *, PTOKEN);
  180. INT WinTicks (LPLINETOKEN *, PTOKEN);
  181.  
  182. INT LocalIF (LPLINETOKEN *, INT);
  183. INT LocalThenElse (LPLINETOKEN *, INT);
  184. INT LocalDO (LPLINETOKEN *, INT);
  185. INT LocalEND (LPLINETOKEN *, INT);
  186. INT LocalWHILE (LPLINETOKEN *, INT);
  187. INT LocalSAY (LPLINETOKEN *, INT);
  188. INT LocalLaunch (LPLINETOKEN *, INT);
  189. INT LocalAssign (LPLINETOKEN *, INT);
  190. INT LocalEXIT (LPLINETOKEN *, INT);
  191. INT LocalRETURN (LPLINETOKEN *, INT);
  192. INT LocalLEAVE (LPLINETOKEN *, INT);
  193. INT LocalChDir (LPLINETOKEN *, INT);
  194. INT LocalCMT2EOL (LPLINETOKEN *, INT);
  195.  
  196. //-----------------------------------------------------------
  197. // Global data
  198. //-----------------------------------------------------------
  199. HANDLE    hInst;
  200. HWND        hMain, hwndLList, hwndOList;
  201. HWND        hwndStepBtn, hwndRunBtn, hwndResetBtn;
  202. BOOL        bMinOnRun = FALSE;
  203. BOOL        bShowOut = FALSE;
  204. BOOL        bShowList = TRUE;
  205. char        *pszAskAns;
  206.  
  207. char szAppName[] = "WinCmd";            // Application name
  208. char szTitleText[] = "WinCmd Window";   // Window text
  209. char szMenuName[] = "WinCmdMenu";       // Menu name
  210. char szIconName[] = "WinCmdIcon";       // Icon name
  211. char szProfileName[] = "WinCmd.ini";    // INI file name
  212.  
  213. LOCALOP OpList[] = {
  214. //  Name     Type       Level  Function
  215.     {")",   TTYPE_CPAREN,  1, LocalOpCPren},
  216.     {"NOT", TTYPE_LUOP,   15, LocalOpNOT},
  217.     {"NOTB",TTYPE_LUOP,   15, LocalOpNOTBits},
  218.     {"*",   TTYPE_LOP,    14, LocalOpMul},
  219.     {"/",   TTYPE_LOP,    14, LocalOpDiv},
  220.     {"+",   TTYPE_LOP,    13, LocalOpAdd},
  221.     {"-",   TTYPE_LUOP,   13, LocalOpSub},
  222.     {"<",   TTYPE_LOP,    11, LocalOpLThan},
  223.     {"<=",  TTYPE_LOP,    11, LocalOpLEThan},
  224.     {">",   TTYPE_LOP,    11, LocalOpGThan},
  225.     {">=",  TTYPE_LOP,    11, LocalOpGEThan},
  226.     {"=",   TTYPE_ASSIGN_CMP, 10, LocalOpCmp},
  227.     {"==",  TTYPE_LOP,    10, LocalOpCmp},
  228.     {"<>",  TTYPE_LOP,    10,  LocalOpNotEqual},
  229.     {"ANDB",TTYPE_LOP,     9,  LocalOpANDBits},
  230.     {"XORB",TTYPE_LOP,     8,  LocalOpXORBits},
  231.     {"ORB", TTYPE_LOP,     7,  LocalOpORBits},
  232.     {"AND", TTYPE_LOP,     6,  LocalOpAND},
  233.     {"OR",  TTYPE_LOP,     5,  LocalOpOR},
  234.     {"XOR", TTYPE_LOP,     5,  LocalOpXOR},
  235.     {",",   TTYPE_BREAK,   1,  LocalComma},
  236. };
  237.  
  238. LOCALFUNC FuncList[] = {
  239. //   Name         Type             Function
  240.     {"(",         TTYPE_OPAREN,    LocalOpOPren},
  241.     {"LENGTH",    TTYPE_LOCALFUNC, LocalLENGTH},
  242.     {"UCASE",     TTYPE_LOCALFUNC, LocalUPPER},
  243.     {"SUBSTR",    TTYPE_LOCALFUNC, LocalSUBSTR},
  244.     {"ARG",       TTYPE_LOCALFUNC, LocalARG},
  245.     {"DELAY",     TTYPE_LOCALFUNC, LocalWAIT},
  246.     {"APPACTIVATE", TTYPE_LOCALFUNC, WinActivate},
  247.     {"GETAPPACTIVE", TTYPE_LOCALFUNC, WinGetActWin},
  248.     {"GETAPPEXE", TTYPE_LOCALFUNC, WinGetWinEXE},
  249.     {"GETNEXTAPP", TTYPE_LOCALFUNC, WinGetNextWin},
  250.     {"SENDKEYS",  TTYPE_LOCALFUNC, WinSendKeys},
  251.     {"MSGBOX",    TTYPE_LOCALFUNC, WinMsgBox},
  252.     {"ASKBOX",    TTYPE_LOCALFUNC, WinAskBox},
  253.     {"TICKS",     TTYPE_LOCALFUNC, WinTicks},
  254. };
  255.  
  256. LOCALSTATEMENT StatementList[] = {
  257. //   Name           Type          Function
  258.     {"WHILE",   TTYPE_LSTATEMENT, LocalWHILE},
  259.     {"IF",      TTYPE_LSTATEMENT, LocalIF},
  260.     {"THEN",    TTYPE_THENELSE,   LocalThenElse},
  261.     {"ELSE",    TTYPE_THENELSE,   LocalThenElse},
  262.     {"DO",      TTYPE_LSTATEMENT, LocalDO},
  263.     {"END",     TTYPE_LSTATEMENT, LocalEND},
  264.     {"EXIT",    TTYPE_LSTATEMENT, LocalEXIT},
  265.     {"RETURN",  TTYPE_LSTATEMENT, LocalRETURN},
  266.     {"LEAVE",   TTYPE_LSTATEMENT, LocalLEAVE},
  267.     {"PRINT",   TTYPE_LSTATEMENT, LocalSAY},
  268.     {"SAY",     TTYPE_LSTATEMENT, LocalSAY},
  269.     {"CD",      TTYPE_LSTATEMENT, LocalChDir},
  270.     {"CHDIR",   TTYPE_LSTATEMENT, LocalChDir},
  271.     {"REM",     TTYPE_CMT2EOL,    LocalCMT2EOL},
  272.     {"//",      TTYPE_CMT2EOL,    LocalCMT2EOL},
  273.     {"'",       TTYPE_CMT2EOL,    LocalCMT2EOL},
  274. };
  275. //
  276. // Table for DOS Internal Commands
  277. //
  278. struct {
  279.    char    *szName;
  280. } CmdList[] = {
  281. //     "name----"
  282.     {"MD"},                  //DOS internal commands
  283. //    {"CD"},
  284.     {"RD"},
  285.     {"CLS"},
  286.     {"DIR"},
  287.     {"DEL"},
  288.     {"REN"},
  289.     {"VER"},
  290.     {"VOL"},
  291.     {"CTTY"},
  292.     {"CHCP"},
  293.     {"TYPE"},
  294.     {"COPY"},
  295.     {"DATE"},
  296.     {"TIME"},
  297.     {"ERASE"},
  298. //    {"CHDIR"},
  299.     {"MKDIR"},
  300.     {"RMDIR"},
  301.     {"BREAK"},
  302.     {"RENAME"},
  303.     {"DELETE"},
  304.     {"VERIFY"},
  305.     {"TRUENAME"},
  306. };
  307.  
  308. struct {
  309.    char    *szName;
  310.    BYTE    ucKey;
  311. } SKList[] = {
  312. //     "name----"  Key
  313.     {"bksp",     VK_BACK},
  314.     {"break",    VK_CANCEL},
  315.     {"capslock", VK_CAPITAL},
  316.     {"clear",    VK_CLEAR},
  317.     {"delete",   VK_DELETE},
  318.     {"down",     VK_DOWN},
  319.     {"end" ,     VK_END},
  320.     {"enter",    VK_RETURN},
  321.     {"esc",      VK_ESCAPE},
  322.     {"help",     VK_HELP},
  323.     {"home",     VK_HOME},
  324.     {"insert",   VK_INSERT},
  325.     {"left",     VK_LEFT},
  326.     {"numlock",  VK_NUMLOCK},
  327.     {"pgdn",     VK_NEXT},
  328.     {"pgup",     VK_PRIOR},
  329.     {"prtsc",    VK_SNAPSHOT},
  330.     {"pause",    VK_PAUSE},
  331.     {"right",    VK_RIGHT},
  332.     {"tab",      VK_TAB},
  333.     {"up",       VK_UP},
  334.     {"scroll",   VK_SCROLL},
  335.     {"F1",       VK_F1},
  336.     {"F2",       VK_F2},
  337.     {"F3",       VK_F3},
  338.     {"F4",       VK_F4},
  339.     {"F5",       VK_F5},
  340.     {"F6",       VK_F6},
  341.     {"F7",       VK_F7},
  342.     {"F8",       VK_F8},
  343.     {"F9",       VK_F9},
  344.     {"F0",       VK_F10},
  345.     {"F11",      VK_F11},
  346.     {"F12",      VK_F12},
  347.     {"F13",      VK_F13},
  348.     {"F14",      VK_F14},
  349.     {"F15",      VK_F15},
  350.     {"F16",      VK_F16},
  351.     {"F17",      VK_F17},
  352.     {"F18",      VK_F18},
  353.     {"F19",      VK_F19},
  354.     {"F20",      VK_F20},
  355.     {"F21",      VK_F21},
  356.     {"F22",      VK_F22},
  357.     {"F23",      VK_F23},
  358.     {"F24",      VK_F24},
  359. };        
  360.  
  361. PTOKEN    ptVarList;
  362. UINT        wVarCount;
  363. PBYTE    pbVarBuff, pbVarStrings;
  364. LPBYTE    lpbTokBuff, lpbTokLine;
  365. HANDLE    hTokBuff, hVarBuff, hFileBuff = 0;
  366. INT        sLibCount = 0;
  367. FARPROC    lpfnLibFunc[MAXLIBS];
  368. HINSTANCE hLib[MAXLIBS];
  369. FARPROC    lpfnTokenFuncCallback;
  370.  
  371. char        szNull[]= "";
  372. char        szProgName[12] = "";
  373. char        szCmdBuff[128] = "";
  374. char        szProgExt[40] = "";
  375. char        szTemp[33];
  376. BOOL        bRunning = FALSE;
  377. BOOL        bHold = FALSE;
  378. BOOL        bProg =TRUE;
  379. BOOL        bAutoStart = FALSE;
  380. BOOL        bAtEnd = FALSE;
  381. UINT        wCurrentLine;
  382. INT        sFinalRC = 0;
  383. UINT     hWaitTimer;
  384.  
  385. //============================================================
  386. // WinMain -- entry point for this application from Windows.
  387. //============================================================
  388. INT APIENTRY WinMain(HANDLE hInstance, HANDLE hPrevInstance, 
  389.                      LPSTR lpCmdLine, INT nCmdShow) {
  390.     MSG    msg;
  391.     INT    rc;
  392.  
  393.     hInst = hInstance;
  394.     //
  395.     // If first instance, perform any init processing
  396.     //    
  397.    if(!hPrevInstance)
  398.         if((rc = InitApp(hInstance)) != 0)
  399.             return rc;
  400.     //
  401.     // Initialize this instance
  402.     //
  403.     if((rc = InitInstance(hInstance, lpCmdLine, nCmdShow)) != 0)
  404.         return rc;
  405.     //
  406.     // Application message loop
  407.     //
  408.     bProg = TRUE;
  409.     while (bProg) {
  410.        if (bHold) {
  411.             bProg = GetMessage (&msg, NULL, 0, 0);
  412.             TranslateMessage(&msg);
  413.             DispatchMessage(&msg);
  414.         } else {
  415.             //Execute Line has a yield call in it
  416.            rc = ExecuteLine (&(LPLINETOKEN)lpbTokLine, FUNC_EXECUTE);
  417.            if (rc) {
  418.               bRunning = FALSE;
  419.               bHold = TRUE;
  420.                 if (rc == RC_END_OF_PROGRAM) {
  421.                     bAtEnd = TRUE;
  422.                     if (bAutoStart)
  423.                        PostMessage (hMain, WM_QUIT, 0, 0);
  424.                     else
  425.                         PostMessage (hMain, MYMSG_REFRESH, 0, 0);
  426.                 } else
  427.                     PrintError (hMain, wCurrentLine, rc, TRUE);
  428.            }
  429.            if (rc == ERR_UNEXP_PROGTERM)
  430.               bProg = FALSE;
  431.         }
  432.     }
  433.     //
  434.     // Instance cleanup
  435.     //
  436.     return TermInstance(hInstance, sFinalRC);
  437. }
  438.   
  439. //-----------------------------------------------------------
  440. // InitApp - Global initialization code for this application.
  441. //-----------------------------------------------------------
  442. INT InitApp(HANDLE hInstance) {
  443.     WNDCLASS     wc;
  444.     //
  445.     // Register App Window class
  446.     //
  447.     wc.style = 0;                             // Window style
  448.     wc.lpfnWndProc = MainWndProc;             // Callback function
  449.     wc.cbClsExtra = 0;                        // Extra class data
  450.     wc.cbWndExtra = 0;                        // Extra window data
  451.     wc.hInstance = hInstance;                 // Owner handle
  452.     wc.hIcon = LoadIcon(hInst, szIconName);   // Application icon
  453.     wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Default cursor
  454.     wc.hbrBackground = COLOR_WINDOW + 1;      // Background color 
  455.     wc.lpszMenuName =  szMenuName;            // Menu name
  456.     wc.lpszClassName = szAppName;             // Window class name
  457.  
  458.     if (RegisterClass(&wc) == 0)
  459.         return 1;
  460.     
  461.     return 0;
  462. }
  463.  
  464. //-----------------------------------------------------------
  465. // InitInstance - Instance initialization code for this app.
  466. //-----------------------------------------------------------
  467. INT InitInstance(HANDLE hInstance, LPSTR lpCmdLine, INT nCmdShow) {
  468.    int    x,y, Cx, Cy, rc = 0;
  469.    char    szErrorStr[50];
  470.  
  471.     x  = GetPrivateProfileInt (szAppName, PRO_XPOS, CW_USEDEFAULT, 
  472.                                szProfileName);
  473.     y  = GetPrivateProfileInt (szAppName, PRO_YPOS, CW_USEDEFAULT, 
  474.                                szProfileName);
  475.     Cx = GetPrivateProfileInt (szAppName, PRO_XSIZE, CW_USEDEFAULT, 
  476.                                szProfileName);
  477.     Cy = GetPrivateProfileInt (szAppName, PRO_YSIZE, CW_USEDEFAULT, 
  478.                                szProfileName);
  479.  
  480.     GetProfileString ("Windows", "Programs", "com exe pif bat",
  481.                       szProgExt, sizeof (szProgExt));
  482.     hMain = CreateWindow(                     // create frame window
  483.                 szAppName,                    // window class name
  484.                 szTitleText,                  // text for title bar
  485.                 WS_OVERLAPPEDWINDOW,          // window style
  486.                 x, y,                         // default position
  487.                 Cx, Cy,                       // default size
  488.                 NULL,                         // no parent window
  489.                 NULL,                         // use class default menu
  490.                 hInstance,                    // window owner
  491.                 NULL);                        // ptr to creation data
  492.  
  493.     if(!hMain) return 0x10;
  494.     lpfnTokenFuncCallback = MakeProcInstance ((FARPROC) TokFuncCallback, hInstance);    
  495.     rc = ParseCmdLine (lpCmdLine);
  496.     if (rc) {
  497.         if (rc > 0)
  498.            rc += 11;
  499.         else 
  500.            rc = abs (rc);
  501.         if (LoadString (hInst, rc, szErrorStr, sizeof (szErrorStr)) == 0) {
  502.             itoa (rc, szTemp, 10);
  503.             strcpy (szErrorStr, "Error number: ");
  504.             strcat (szErrorStr, szTemp);
  505.         }
  506.         MessageBox (hMain, szErrorStr, szAppName, MB_OK | MB_ICONHAND);
  507.         return 0;
  508.     }
  509.     rc = InitInterpeter (hMain);
  510.     if (rc) {
  511.         if (rc > 0)
  512.            rc += 11;
  513.         else 
  514.            rc = abs (rc);
  515.         if (LoadString (hInst, rc, szErrorStr, sizeof (szErrorStr)) == 0) {
  516.             itoa (rc, szTemp, 10);
  517.             strcpy (szErrorStr, "Error number: ");
  518.             strcat (szErrorStr, szTemp);
  519.         }
  520.         MessageBox (hMain, szErrorStr, szAppName, MB_OK | MB_ICONHAND);
  521.         return rc;
  522.     }
  523.     if (bAutoStart) 
  524.        ShowWindow(hMain, nCmdShow | SW_SHOW | SW_MINIMIZE);
  525.     else
  526.         ShowWindow(hMain, nCmdShow | SW_SHOW);
  527.     UpdateWindow(hMain);              // force WM_PAINT message
  528.     return 0;                         // return success flag
  529. }
  530.  
  531. //------------------------------------------------------------
  532. // TermInstance - Instance termination code for this app.
  533. //------------------------------------------------------------
  534. INT TermInstance(HANDLE hinstance, int sDefRC) {
  535.    TermInterpeter ();
  536.     return sDefRC;
  537. }
  538.  
  539. //============================================================
  540. // Message handling procedures for MainWindow
  541. //============================================================
  542. //------------------------------------------------------------
  543. // MainWndProc - Callback function for application window
  544. //------------------------------------------------------------
  545. LONG CALLBACK MainWndProc(HWND hWnd, UINT wMsg, UINT wParam, 
  546.                           LONG lParam) {
  547.     INT i;
  548.     //
  549.     // Search message list to see if we need to handle this
  550.     // message.  If in list, call procedure.
  551.     //
  552.     for(i = 0; i < dim(MainMessages); i++) {
  553.         if(wMsg == MainMessages[i].Code)
  554.             return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
  555.     }
  556.     return DefWindowProc(hWnd, wMsg, wParam, lParam);
  557. }
  558.  
  559. //------------------------------------------------------------
  560. // GetLListPos - Computes the position of the source listbox
  561. //------------------------------------------------------------ 
  562. void GetLListPos (HWND hWnd, INT *x, INT *y, INT *Cx, INT *Cy, UINT *fFlags){
  563.    RECT    rect;
  564.    INT    sWinHeight, sWinWidth;
  565.  
  566.     GetClientRect (hWnd, &rect);
  567.     sWinHeight = rect.bottom - rect.top;
  568.     sWinWidth = rect.right - rect.left;
  569.  
  570.    if (bShowList) 
  571.         *fFlags = SWP_SHOWWINDOW;
  572.     else    
  573.         *fFlags = SWP_HIDEWINDOW;
  574.  
  575.       *x = 10;
  576.       *Cx = sWinWidth - 90;
  577.    if (bShowOut) {
  578.        *y = sWinHeight/2 + 10;
  579.        *Cy = sWinHeight/2 - 10;
  580.    } else {
  581.        *y = 10;
  582.        *Cy = sWinHeight - 10;
  583.    }
  584.     return;
  585. }    
  586. //------------------------------------------------------------
  587. // GetOListPos - Computes the position of the source listbox
  588. //------------------------------------------------------------ 
  589. void GetOListPos (HWND hWnd, INT *x, INT *y, INT *Cx, INT *Cy, UINT *fFlags){
  590.    RECT    rect;
  591.    INT    sWinHeight, sWinWidth;
  592.  
  593.     GetClientRect (hWnd, &rect);
  594.     sWinHeight = rect.bottom - rect.top;
  595.     sWinWidth = rect.right - rect.left;
  596.  
  597.    if (bShowOut) 
  598.         *fFlags = SWP_SHOWWINDOW;
  599.     else    
  600.         *fFlags = SWP_HIDEWINDOW;
  601.  
  602.       *x = 10;
  603.       *y = 10;
  604.       *Cx = sWinWidth - 90;
  605.    if (bShowList) 
  606.        *Cy = sWinHeight/2 - 10;
  607.    else
  608.        *Cy = sWinHeight - 10;
  609.     return;
  610. }    
  611.  
  612. //------------------------------------------------------------
  613. // GetBtnPos - Computes the position of the buttons
  614. //------------------------------------------------------------ 
  615. void GetBtnPos (HWND hWnd, INT *x, INT *y, INT *Cx, INT *Cy, INT sNum) {
  616.    RECT    rect;
  617.    INT    sWinHeight, sWinWidth;
  618.  
  619.     GetClientRect (hWnd, &rect);
  620.     sWinHeight = rect.bottom - rect.top;
  621.     sWinWidth = rect.right - rect.left;
  622.  
  623.     *x = sWinWidth - 75;
  624.     *y = 30 + (35 * sNum);
  625.       *Cx = 70;
  626.       *Cy = 30;
  627.     return;
  628. }    
  629. //------------------------------------------------------------
  630. // DoCreateMain - process WM_CREATE message for frame window.
  631. //------------------------------------------------------------ 
  632. LONG DoCreateMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  633.    DWORD    dwStyle;
  634.    INT    x,y,Cx,Cy;
  635.    UINT    fFlags;
  636.    RECT    rect;
  637.    INT    sWinWidth;
  638.  
  639.     GetClientRect (hWnd, &rect);
  640.     sWinWidth = rect.right - rect.left;
  641.  
  642.     //Create Child Windows 
  643.     GetLListPos (hWnd, &x, &y, &Cx, &Cy, &fFlags);
  644.    if (bShowList) 
  645.         dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL |
  646.                   LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_USETABSTOPS;
  647.     else
  648.         dwStyle = WS_CHILD | WS_BORDER | WS_VSCROLL |
  649.                   LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_USETABSTOPS;
  650.     hwndLList = CreateWindow ("listbox", NULL, dwStyle,
  651.                      x, y,                             // Pos
  652.                      Cx, Cy,                           // Size
  653.                      hWnd,                             //Parent handle
  654.                      IDD_LINELIST,                     //ID number
  655.                      hInst, NULL);
  656.     SendDlgItemMessage (hWnd, IDD_LINELIST, LB_SETTABSTOPS, 1, 
  657.                         (LPARAM)(LPINT)&x);
  658.  
  659.     GetOListPos (hWnd, &x, &y, &Cx, &Cy, &fFlags);    
  660.    if (bShowOut) 
  661.         dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL |
  662.                   LBS_NOTIFY | LBS_DISABLENOSCROLL | LBS_USETABSTOPS;
  663.     else    
  664.         dwStyle = WS_CHILD | WS_BORDER | WS_VSCROLL |
  665.                   LBS_NOTIFY | LBS_DISABLENOSCROLL;
  666.     hwndOList = CreateWindow ("listbox", NULL, dwStyle,
  667.                      x, y,                             // Pos
  668.                      Cx, Cy,                           // Size
  669.                      hWnd,                             //Parent handle
  670.                      IDD_OUTLIST,                      //ID number
  671.                      hInst, NULL);
  672.  
  673.     x = 14;
  674.     SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_SETTABSTOPS, 1, 
  675.                         (LPARAM)(LPINT)&x);
  676.  
  677.     GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 0);
  678.     hwndRunBtn = CreateWindow ("button", "Run",
  679.                      WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
  680.                      x, y,                             // Pos
  681.                      Cx, Cy,                           // Size
  682.                      hWnd,                             //Parent handle
  683.                      IDD_RUN,                          //ID number
  684.                      hInst, NULL);
  685.     GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 1);
  686.     hwndStepBtn = CreateWindow ("button", "Step",
  687.                      WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
  688.                      x, y,                             // Pos
  689.                      Cx, Cy,                           // Size
  690.                      hWnd,                             //Parent handle
  691.                      IDD_STEP,                         //ID number
  692.                      hInst, NULL);
  693.     GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 2);
  694.     hwndResetBtn = CreateWindow ("button", "Reset",
  695.                      WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
  696.                      x, y,                             // Pos
  697.                      Cx, Cy,                           // Size
  698.                      hWnd,                             //Parent handle
  699.                      IDD_RESET,                        //ID number
  700.                      hInst, NULL);
  701.  
  702.     return 0;         
  703. }
  704. //------------------------------------------------------------
  705. // DoSizeMain - process WM_SIZE message for frame window.
  706. //------------------------------------------------------------ 
  707. LONG DoSizeMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  708.  
  709.    SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
  710.     return 0;         
  711. }
  712. //------------------------------------------------------------
  713. // DoTimerMain - process WM_TIMER message for frame window.
  714. //------------------------------------------------------------ 
  715. LONG DoTimerMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  716.  
  717.     if (wParam == WAITTIMER_ID) {
  718.        bHold = FALSE;
  719.        KillTimer (hWnd, hWaitTimer);
  720.     }   
  721.     return 0;         
  722. }
  723.  
  724. //------------------------------------------------------------
  725. // DoInitMenuMain - process WM_INITMENU message
  726. //------------------------------------------------------------ 
  727. LONG DoInitMenuMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  728.  
  729.     if (bShowList)    
  730.         CheckMenuItem (GetMenu(hWnd), IDM_SHOWLIST,
  731.                        MF_BYCOMMAND | MF_CHECKED);
  732.     else                       
  733.         CheckMenuItem (GetMenu(hWnd), IDM_SHOWLIST,
  734.                        MF_BYCOMMAND | MF_UNCHECKED);
  735.     if (bShowOut)    
  736.         CheckMenuItem (GetMenu(hWnd), IDM_SHOWOUT,
  737.                        MF_BYCOMMAND | MF_CHECKED);
  738.     else                       
  739.         CheckMenuItem (GetMenu(hWnd), IDM_SHOWOUT,
  740.                        MF_BYCOMMAND | MF_UNCHECKED);
  741.     if (bMinOnRun)    
  742.         CheckMenuItem (GetMenu(hWnd), IDM_MINONRUN,
  743.                        MF_BYCOMMAND | MF_CHECKED);
  744.     else                       
  745.         CheckMenuItem (GetMenu(hWnd), IDM_MINONRUN,
  746.                        MF_BYCOMMAND | MF_UNCHECKED);
  747.     return 0;         
  748. }
  749.  
  750. //------------------------------------------------------------
  751. // DoRefreshMain - Refresh main windows.  This procedure
  752. // is called by the user defined MYMSG_REFRESH message
  753. //------------------------------------------------------------ 
  754. LONG DoRefreshMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  755.    INT    x,y,Cx,Cy;
  756.    UINT    fFlags;
  757.  
  758.     GetLListPos (hWnd, &x, &y, &Cx, &Cy, &fFlags);
  759.     SetWindowPos (hwndLList, 0, x, y, Cx, Cy, fFlags);
  760.     GetOListPos (hWnd, &x, &y, &Cx, &Cy, &fFlags);
  761.     SetWindowPos (hwndOList, 0, x, y, Cx, Cy, fFlags);
  762.  
  763.     GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 0);    
  764.     SetWindowPos (hwndRunBtn, 0, x, y, Cx, Cy, SWP_NOZORDER);
  765.     GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 1);    
  766.     SetWindowPos (hwndStepBtn, 0, x, y, Cx, Cy, SWP_NOZORDER);
  767.     GetBtnPos (hWnd, &x, &y, &Cx, &Cy, 2);    
  768.     SetWindowPos (hwndResetBtn, 0, x, y, Cx, Cy, SWP_NOZORDER);
  769.  
  770.     if (szCmdBuff[0] == 0) {
  771.         EnableWindow (GetDlgItem (hWnd, IDD_STEP), FALSE);
  772.         EnableWindow (GetDlgItem (hWnd, IDD_RESET), FALSE);
  773.         SetDlgItemText (hWnd, IDD_RUN, "Run");
  774.         EnableWindow (GetDlgItem (hWnd, IDD_RUN), FALSE);
  775.     } else {
  776.         if (bRunning) {
  777.             EnableWindow (GetDlgItem (hWnd, IDD_STEP), FALSE);
  778.             EnableWindow (GetDlgItem (hWnd, IDD_RESET), FALSE);
  779.             SetDlgItemText (hWnd, IDD_RUN, "Stop");
  780.         } else {
  781.             SetDlgItemText (hWnd, IDD_RUN, "Run");
  782.             EnableWindow (GetDlgItem (hWnd, IDD_RESET), TRUE);
  783.            if (bAtEnd) 
  784.                 EnableWindow (GetDlgItem (hWnd, IDD_STEP), FALSE);
  785.             else
  786.                 EnableWindow (GetDlgItem (hWnd, IDD_STEP), TRUE);
  787.         }    
  788.         EnableWindow (GetDlgItem (hWnd, IDD_RUN), TRUE);
  789.     }    
  790.     SendDlgItemMessage (hMain, IDD_LINELIST, LB_SETCURSEL, wCurrentLine, 0);
  791.     return 0;         
  792. }
  793.  
  794. //------------------------------------------------------------
  795. // DoCommandMain - process WM_COMMAND message for frame window 
  796. // by decoding the menubar item with the menuitems[] array, 
  797. // then running the corresponding function to process the command.
  798. //------------------------------------------------------------ 
  799. LONG DoCommandMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  800.     INT    i;
  801.     UINT    idItem, wNotifyCode;
  802.     HWND    hwndCtl;
  803.  
  804.     idItem = (UINT) wParam;                      // Parse Parameters
  805.     hwndCtl = (HWND) LOWORD(lParam);
  806.     wNotifyCode = (UINT) HIWORD(lParam);
  807.     //
  808.     // Call routine to handle control message
  809.     //
  810.     for(i = 0; i < dim(MainMenuItems); i++) {
  811.         if(idItem == MainMenuItems[i].Code)
  812.             return (*MainMenuItems[i].Fxn)(hWnd, idItem, hwndCtl, 
  813.                                            wNotifyCode);
  814.     }
  815.     return DefWindowProc(hWnd, wMsg, wParam, lParam);
  816. }
  817.  
  818. //------------------------------------------------------------
  819. // DoDestroyMain - process WM_DESTROY message for frame window.
  820. //------------------------------------------------------------ 
  821. LONG DoDestroyMain (HWND hWnd, UINT wMsg, UINT wParam, LONG lParam) {
  822.    RECT    rect;
  823.    
  824.    if (hFileBuff)
  825.       GlobalFree (hFileBuff);
  826.    
  827.    bRunning = FALSE;
  828.    bHold = TRUE;
  829.    
  830.     //Save Window position
  831.     if    (!IsIconic (hWnd) && !IsZoomed (hWnd)) {
  832.         GetWindowRect (hWnd, &rect);
  833.         MyWritePrivateProfileInt (szAppName, PRO_XPOS, rect.left,
  834.                                   10, szProfileName);
  835.         MyWritePrivateProfileInt (szAppName, PRO_YPOS, rect.top,
  836.                                   10, szProfileName);
  837.         MyWritePrivateProfileInt (szAppName, PRO_XSIZE, 
  838.                                   rect.right - rect.left,
  839.                                   10, szProfileName);
  840.         MyWritePrivateProfileInt (szAppName, PRO_YSIZE, 
  841.                                   rect.bottom - rect.top,
  842.                                   10, szProfileName);
  843.     }
  844.     PostQuitMessage (0);
  845.     return 0;         
  846. }
  847.  
  848. //============================================================
  849. // Control handling procedures for MainWindow
  850. //============================================================
  851. //------------------------------------------------------------
  852. // DoMainCtlRun - Process Run button
  853. //------------------------------------------------------------ 
  854. LONG DoMainCtlRun (HWND hWnd, UINT idItem, HWND hwndCtl, 
  855.                      UINT wNotifyCode) {
  856.     if (bRunning) {                        
  857.         bRunning = FALSE;
  858.         bShowList = TRUE;
  859.         bHold = TRUE;
  860.     } else {    
  861.        if (!bAtEnd) {
  862.             bRunning = TRUE;
  863.             bHold = FALSE;
  864.  
  865.             bShowList = FALSE;
  866.             bShowOut = TRUE;
  867.             if (bMinOnRun)
  868.                ShowWindow (hWnd, SW_SHOWMINIMIZED);
  869.         }
  870.         else
  871.            return 0;
  872.     }    
  873.     SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
  874.     return 0;
  875. }
  876. //------------------------------------------------------------
  877. // DoMainCtlStep - Process Step button
  878. //------------------------------------------------------------ 
  879. LONG DoMainCtlStep (HWND hWnd, UINT idItem, HWND hwndCtl, 
  880.                      UINT wNotifyCode) {
  881.     bHold = FALSE;
  882.     return 0;
  883. }
  884. //------------------------------------------------------------
  885. // DoMainCtlReset - Process Reset button
  886. //------------------------------------------------------------ 
  887. LONG DoMainCtlReset (HWND hWnd, UINT idItem, HWND hwndCtl, 
  888.                      UINT wNotifyCode) {
  889.     INT    sRC;                        
  890.     if (bRunning) 
  891.        return 0;                       
  892.  
  893.     sRC = ResetInterpeter (hWnd);
  894.     if (sRC)
  895.        PrintError (hWnd, 0, sRC, TRUE);
  896.     else {
  897.         bShowList = TRUE;
  898.         bShowOut = FALSE;
  899.     }    
  900.     SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
  901.     return 0;
  902. }
  903.  
  904. //============================================================
  905. // Menu handling procedures for MainWindow
  906. //============================================================
  907. //------------------------------------------------------------
  908. // DoMainMenuFileOpen - Process File/Open menu item
  909. //------------------------------------------------------------ 
  910. LONG DoMainMenuFileOpen (HWND hWnd, UINT idItem, HWND hwndCtl, 
  911.                          UINT wNotifyCode) {
  912.     int    sRC;
  913.     static char *szFilter[] = {"WinCmd Files (*.WCM)", "*.WCM",
  914.                                "All Files (*.*)", "*.*", "" };
  915.  
  916.     MyGetFilename (hWnd, szCmdBuff, sizeof (szCmdBuff)-1, *szFilter, 1);
  917.     szCmdBuff[strlen (szCmdBuff)+1] = 0;
  918.  
  919.     sRC = ResetInterpeter (hWnd);
  920.     if (sRC)
  921.        PrintError (hWnd, 0, sRC, TRUE);
  922.     else {
  923.         bShowList = TRUE;
  924.         bShowOut = FALSE;
  925.     }
  926.     return 0;
  927. }
  928. //------------------------------------------------------------
  929. // DoMainMenuFileLoad - Process File/Load Lib menu item
  930. //------------------------------------------------------------ 
  931. LONG DoMainMenuFileLoad (HWND hWnd, UINT idItem, HWND hwndCtl, 
  932.                          UINT wNotifyCode) {
  933.     static char *szFilter[] = {"Libraries (*.dll)", "*.DLL",
  934.                                "All Files (*.*)", "*.*", "" };
  935.  
  936.     char        szLibName[128];    
  937.     int        sRC;
  938.     FARPROC    lpfnLibLoad;
  939.  
  940.     if (sLibCount == MAXLIBS)
  941.        return 0;
  942.     MyGetFilename (hWnd, szLibName, sizeof (szLibName), *szFilter, 1);
  943.  
  944.     hLib[sLibCount] = LoadLibrary (szLibName);
  945.     if (hLib[sLibCount] < 32) {
  946.        PrintError (hWnd, 0, ERR_LAUNCH_ERR - sRC, TRUE);
  947.        return 0;
  948.     }
  949.     lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibFunc");
  950.     
  951.     lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibLoad");
  952.     if (lpfnLibLoad == 0) {
  953.        FreeLibrary (hLib[sLibCount]);
  954.        PrintError (hWnd, 0, ERR_BAD_LIB_LOAD, TRUE);
  955.        return 0;
  956.     }
  957.     sRC = ((LPLIBLOAD)*lpfnLibLoad) (hWnd, sLibCount, ERR_LIBERROR_START - sLibCount);
  958.     if (sRC) {
  959.        PrintError (hWnd, 0, ERR_BAD_LIB_LOAD, TRUE);
  960.        FreeLibrary (hLib[sLibCount]);
  961.        return 0;
  962.     }
  963.     lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibFunc");
  964.     if (lpfnLibLoad == 0) { 
  965.        PrintError (hWnd, 0, ERR_BAD_LIB_LOAD, TRUE);
  966.        FreeLibrary (hLib[sLibCount]);
  967.        return 0;
  968.     }
  969.     lpfnLibFunc[sLibCount] = lpfnLibLoad;
  970.     sLibCount++;
  971.  
  972.     sRC = ResetInterpeter (hWnd);
  973.     if (sRC)
  974.        PrintError (hWnd, 0, sRC, TRUE);
  975.     else {
  976.         bShowList = TRUE;
  977.         bShowOut = FALSE;
  978.     }
  979.     return 0;
  980. }
  981. //------------------------------------------------------------
  982. // DoMainMenuShowList - Process View/Show Listing menu item
  983. //------------------------------------------------------------ 
  984. LONG DoMainMenuShowList (HWND hWnd, UINT idItem, HWND hwndCtl, 
  985.                          UINT wNotifyCode) {
  986.  
  987.     if (bShowList)
  988.        bShowList = FALSE;
  989.     else
  990.        bShowList = TRUE;
  991.     SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
  992.     return 0;
  993. }
  994. //------------------------------------------------------------
  995. // DoMainMenuShowOut - Process View/Show Output menu item
  996. //------------------------------------------------------------ 
  997. LONG DoMainMenuShowOut (HWND hWnd, UINT idItem, HWND hwndCtl, 
  998.                          UINT wNotifyCode) {
  999.  
  1000.     if (bShowOut)
  1001.        bShowOut = FALSE;
  1002.     else
  1003.        bShowOut = TRUE;
  1004.     SendMessage (hWnd, MYMSG_REFRESH, 0, 0);
  1005.     return 0;
  1006. }
  1007. //------------------------------------------------------------
  1008. // DoMainMenuClearOut - Process View/Clear Output menu item
  1009. //------------------------------------------------------------ 
  1010. LONG DoMainMenuClearOut (HWND hWnd, UINT idItem, HWND hwndCtl, 
  1011.                          UINT wNotifyCode) {
  1012.  
  1013.     SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_RESETCONTENT, 0, 0);
  1014.     return 0;
  1015. }
  1016. //------------------------------------------------------------
  1017. // DoMainMenuMinOnRun - Process View/Minimize on Run menu item
  1018. //------------------------------------------------------------ 
  1019. LONG DoMainMenuMinOnRun (HWND hWnd, UINT idItem, HWND hwndCtl, 
  1020.                          UINT wNotifyCode) {
  1021.  
  1022.     if (bMinOnRun)
  1023.        bMinOnRun = FALSE;
  1024.     else
  1025.        bMinOnRun = TRUE;
  1026.     return 0;
  1027. }
  1028. //------------------------------------------------------------
  1029. // DoMainMenuFileExit - Process File/Exit menu item
  1030. //------------------------------------------------------------ 
  1031. LONG DoMainMenuFileExit (HWND hWnd, UINT idItem, HWND hwndCtl, 
  1032.                          UINT wNotifyCode) {
  1033.  
  1034.     DestroyWindow (hWnd);  //Destroy window
  1035.     return 0;
  1036. }
  1037. //------------------------------------------------------------
  1038. // DoMenuAbout - Process File-About command from menu bar.
  1039. //------------------------------------------------------------ 
  1040. LONG DoMainMenuAbout (HWND hWnd, UINT idItem, HWND hwndCtl, 
  1041.                       UINT wNotifyCode) {
  1042.  
  1043.     MyDisplayDialog(hInst, "AboutBox", hWnd, 
  1044.                     (WNDPROC) AboutDlgProc, 0L);
  1045.     return 0;
  1046. }
  1047. //============================================================
  1048. // AboutDlgProc - About dialog box dialog procedure
  1049. //============================================================
  1050. BOOL CALLBACK AboutDlgProc (HWND hWnd, UINT msg, UINT wParam, 
  1051.                             LONG lParam) {
  1052.                               
  1053.     if((msg == WM_COMMAND) && (wParam == IDOK)) {
  1054.         EndDialog(hWnd, 0);
  1055.         return TRUE;
  1056.     } 
  1057.     return FALSE;
  1058. }
  1059. //============================================================
  1060. // AskDlgProc - Ask box dialog box dialog procedure
  1061. //============================================================
  1062. BOOL CALLBACK AskDlgProc (HWND hWnd, UINT msg, UINT wParam, 
  1063.                             LONG lParam) {
  1064.     RECT    rectDesk, rectWnd;                              
  1065.     INT    x, y;
  1066.  
  1067.     if (msg == WM_INITDIALOG) {
  1068.        //First, center the box on the screen.
  1069.        GetWindowRect (GetDesktopWindow(), &rectDesk);
  1070.        GetWindowRect (hWnd, &rectWnd);
  1071.        x = (rectDesk.right-rectDesk.left)/2-(rectWnd.right-rectWnd.left)/2;
  1072.        y = (rectDesk.bottom-rectDesk.top)/2-(rectWnd.bottom-rectWnd.top)/2;
  1073.        SetWindowPos (hWnd, 0, x, y, 0, 0, SWP_NOSIZE);
  1074.  
  1075.        //Set the approperate text fields.
  1076.         SetWindowText (hWnd, szProgName);
  1077.           SetDlgItemText (hWnd, IDD_ASKTEXT, (char *)LOWORD (lParam));
  1078.        SetDlgItemText (hWnd, IDD_ASKANS, (char *)HIWORD (lParam));
  1079.         return 1;                           
  1080.     }           
  1081.                               
  1082.     if (msg == WM_COMMAND) {
  1083.         if(wParam == IDOK) {
  1084.            GetDlgItemText (hWnd, IDD_ASKANS, pszAskAns, MAXLINELEN);
  1085.             EndDialog(hWnd, 1);
  1086.             return TRUE;
  1087.         } else if (wParam == IDCANCEL) {
  1088.             EndDialog(hWnd, 0);
  1089.             return TRUE;
  1090.         }    
  1091.     } 
  1092.     return FALSE;
  1093. }
  1094.  
  1095. //============================================================  
  1096. // General Helper Routines 
  1097. //============================================================  
  1098. //------------------------------------------------------------
  1099. // MyYield - Yields control to other programs, but returns
  1100. // if Windows is idle.
  1101. //------------------------------------------------------------
  1102. BOOL MyYield (void) {
  1103.    MSG    msg;
  1104.    BOOL    bCont;
  1105.    
  1106.    bCont = TRUE;
  1107.     while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  1108.        if (msg.message == WM_QUIT)
  1109.           bCont = FALSE;
  1110.         TranslateMessage(&msg);
  1111.         DispatchMessage(&msg);
  1112.     }
  1113.     return bCont;
  1114. }
  1115. //------------------------------------------------------------
  1116. // MyDisplayDialog - Display a dialog box
  1117. //------------------------------------------------------------ 
  1118. INT MyDisplayDialog (HINSTANCE hInstance, LPCSTR szDlgName,
  1119.                      HWND hWnd, WNDPROC lpDialogProc, 
  1120.                      LPARAM lParam) {
  1121.     WNDPROC lpDlgProcInst;
  1122.     INT        rc;
  1123.  
  1124.     lpDlgProcInst = MakeProcInstance(lpDialogProc, hInst);
  1125.     rc = DialogBoxParam (hInstance, szDlgName, hWnd, 
  1126.                          lpDlgProcInst, lParam);
  1127.     FreeProcInstance(lpDlgProcInst);
  1128.     return rc;                              
  1129. }
  1130. //------------------------------------------------------------
  1131. // MyWritePrivateProfileInt - Writes an integer to the profile
  1132. //------------------------------------------------------------
  1133. BOOL MyWritePrivateProfileInt (char *szSec, char *szEntry, 
  1134.                                int Num, int Base, char *szProfile) {
  1135.     char    szStr[33];
  1136.                                
  1137.     itoa (Num, szStr, Base);
  1138.     return WritePrivateProfileString (szSec, szEntry, szStr, 
  1139.                                       szProfile);
  1140. }
  1141.  
  1142. //------------------------------------------------------------
  1143. // MyGetFilename - Uses the common File Open dialog box to
  1144. // query the user for a filename
  1145. //------------------------------------------------------------
  1146. BOOL MyGetFilename (HWND hWnd, char *szFilename, INT sMaxLen, char *szFilter,
  1147.                     INT sFilterIndex) {
  1148.  
  1149.    OPENFILENAME ofn;
  1150.  
  1151.    *szFilename = '\0';
  1152.  
  1153.     ofn.lStructSize = sizeof (OPENFILENAME);
  1154.     ofn.hwndOwner = hWnd;
  1155.     ofn.hInstance = hInst;
  1156.     ofn.lpstrFilter = szFilter;
  1157.     ofn.lpstrCustomFilter = 0;
  1158.     ofn.nMaxCustFilter = 0;
  1159.     ofn.nFilterIndex = sFilterIndex;
  1160.     ofn.lpstrFile = szFilename;
  1161.     ofn.nMaxFile = sMaxLen;
  1162.     ofn.lpstrFileTitle = 0;
  1163.     ofn.nMaxFileTitle = 0;
  1164.     ofn.lpstrInitialDir = 0;
  1165.     ofn.lpstrTitle = 0;
  1166.     ofn.Flags = OFN_FILEMUSTEXIST;
  1167.     ofn.nFileOffset = 0;
  1168.     ofn.nFileExtension = 0;
  1169.     ofn.lpstrDefExt = "WBT";
  1170.     ofn.lCustData = 0;
  1171.     ofn.lpfnHook = 0;
  1172.     ofn.lpTemplateName = 0;
  1173.  
  1174.      return (GetOpenFileName (&ofn));
  1175. }
  1176.  
  1177.  
  1178. //------------------------------------------------------------
  1179. // MySubClassWindow - Subclasses a window 
  1180. //------------------------------------------------------------
  1181. WNDPROC MySubClassWindow (HWND hWnd, WNDPROC lpfnNewProc) {
  1182.    WNDPROC lpfnOldProc;
  1183.  
  1184.     lpfnOldProc = (WNDPROC) GetWindowLong (hWnd, GWL_WNDPROC);
  1185.     SetWindowLong (hWnd, GWL_WNDPROC, (LONG) lpfnNewProc);
  1186.     return lpfnOldProc;                               
  1187. }                               
  1188.  
  1189. //============================================================  
  1190. // Program specific procedures
  1191. //============================================================
  1192. //============================================================
  1193. // Start of Interpeter code
  1194. //============================================================
  1195.  
  1196. //------------------------------------------------------------
  1197. // InitInterpeter - Initializes the interpeter 
  1198. //------------------------------------------------------------ 
  1199. INT InitInterpeter (HWND hWnd) {
  1200.    INT        sRC;
  1201.     FARPROC    lpfnLibLoad;
  1202.     FIND_T    fs;
  1203.  
  1204.     hVarBuff = LocalAlloc (LMEM_MOVEABLE, (UINT) VARBUFFSIZE);
  1205.     if (hVarBuff == 0) return ERR_OUT_OF_MEMORY;
  1206.     pbVarBuff = LocalLock (hVarBuff);
  1207.  
  1208.     hTokBuff = GlobalAlloc (GMEM_MOVEABLE | LMEM_ZEROINIT, TOKBUFFSIZE);
  1209.     if (hTokBuff == 0) return ERR_OUT_OF_MEMORY;
  1210.     lpbTokBuff = GlobalLock (hTokBuff);
  1211.  
  1212.     sRC = _dos_findfirst ("*.WCL", _A_NORMAL, &fs);
  1213.     while (sRC == 0) {
  1214.  
  1215.         hLib[sLibCount] = LoadLibrary (fs.name);
  1216.         if (hLib[sLibCount] < 32) {
  1217.            sRC = ERR_BAD_LIB_LOAD;
  1218.            FreeLibrary (hLib[sLibCount]);
  1219.            break;
  1220.         }
  1221.         lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibLoad");
  1222.         if (lpfnLibLoad == 0) {
  1223.            sRC = ERR_BAD_LIB_LOAD;
  1224.            FreeLibrary (hLib[sLibCount]);
  1225.            break;
  1226.         }
  1227.         sRC = ((LPLIBLOAD)*lpfnLibLoad) (hWnd, sLibCount, ERR_LIBERROR_START - sLibCount);
  1228.         if (sRC) {
  1229.            sRC = ERR_BAD_LIB_LOAD;
  1230.            FreeLibrary (hLib[sLibCount]);
  1231.            break;
  1232.         }
  1233.         lpfnLibLoad = GetProcAddress (hLib[sLibCount], "WCLibFunc");
  1234.         if (lpfnLibLoad == 0) { 
  1235.            sRC = ERR_BAD_LIB_LOAD;
  1236.            FreeLibrary (hLib[sLibCount]);
  1237.            break;
  1238.         }
  1239.         lpfnLibFunc[sLibCount] = lpfnLibLoad;
  1240.         sLibCount++;
  1241.         sRC = _dos_findnext (&fs);
  1242.     }
  1243.     //If loop term due to file not found, RC = 0;
  1244.     if (sRC == 2) sRC = 0;
  1245. //    for (i=0; i<MAXLIBS;i++)
  1246. //       hLib[i]=0;
  1247.  
  1248.     sRC = ResetInterpeter (hWnd);    
  1249.     if (sRC) return sRC;
  1250.     if (bAutoStart) {
  1251.         bRunning = TRUE;
  1252.         bShowList = FALSE;
  1253.         bShowOut = TRUE;
  1254.     }    
  1255.     return sRC;
  1256. }   
  1257.  
  1258. //------------------------------------------------------------
  1259. // ResetInterpeter - Resets the interpeter and loads a file.
  1260. //------------------------------------------------------------ 
  1261. INT ResetInterpeter (HWND hWnd) {
  1262.    INT        sRC = 0, i, j;
  1263.    PTOKEN    ptArg0;
  1264.    HCURSOR    hcurSave;
  1265.    FARPROC    lpfnLibReset;
  1266.     
  1267.     pbVarStrings = pbVarBuff;
  1268.     ptVarList = (PTOKEN) (pbVarStrings + VARBUFFSIZE);
  1269.       wVarCount = 0;
  1270.     lpbTokLine = lpbTokBuff;
  1271.  
  1272.     // Add Operators to token list
  1273.    for (i = 0; i < dim (OpList); i++) {
  1274.         sRC = AddTokenInit (OpList[i].szName, OpList[i].ucType, 
  1275.                             (WORD) OpList[i].ucLevel,
  1276.                             (DWORD) (LPVOID) OpList[i].Fxn);
  1277.         if (sRC) break;
  1278.     }    
  1279.     // Add DOS internal commands to token list
  1280.    for (i = 0; i < dim (CmdList); i++) {
  1281.         sRC = AddTokenInit (CmdList[i].szName, TTYPE_INTCMD, 0, 0);
  1282.         if (sRC) break;
  1283.     }    
  1284.     // Add Functions to token list
  1285.    for (i = 0; i < dim (FuncList); i++) {
  1286.         sRC = AddTokenInit (FuncList[i].szName, FuncList[i].ucType, 0,
  1287.                             (DWORD)(LPVOID) FuncList[i].Fxn);
  1288.         if (sRC) break;
  1289.     }    
  1290.     // Add Statements to token list
  1291.    for (i = 0; i < dim (StatementList); i++) {
  1292.         sRC = AddTokenInit (StatementList[i].szName, 
  1293.                             StatementList[i].ucType, 0,
  1294.                             (DWORD)(LPVOID) StatementList[i].Fxn);
  1295.         if (sRC) break;
  1296.     }    
  1297.     // Load Predefined Vars
  1298.     AddToken ("HINST", TTYPE_NUM, 0, (DWORD) hInst, &sRC);
  1299.     AddToken ("HMAIN", TTYPE_NUM, 0, (DWORD) hMain, &sRC);
  1300.     // Load Cmd line arg Tokens
  1301.     i = 0;
  1302.     ptArg0 = AddToken ("", TTYPE_STR, 0, (DWORD)(LPSTR) szCmdBuff, &sRC);
  1303.     if (szCmdBuff[0] != 0) {
  1304.         for (i = 0; szCmdBuff[i] != 0; i++)
  1305.            ;
  1306.         i++;
  1307.     }    
  1308.     j = 1;
  1309.     while ((szCmdBuff[i] != 0) && (sRC == 0)) {
  1310.         AddToken ("",TTYPE_STR, 0, (DWORD)(LPSTR)&szCmdBuff[i], &sRC);
  1311.         for (; szCmdBuff[i] != 0; i++)
  1312.            ;
  1313.         i++;
  1314.         j++;
  1315.     }
  1316.     if (sRC) return sRC;
  1317.     AddToken ("",TTYPE_RETVAL, j, (DWORD)(LPVOID)ptArg0, &sRC);
  1318.  
  1319.     // Add Library Tokens
  1320.    for (i = 0; i < sLibCount; i++) {
  1321.         lpfnLibReset = GetProcAddress (hLib[i], "WCLibReset");
  1322.         if (lpfnLibReset == 0)
  1323.            sRC = ERR_BAD_LIB_LOAD;
  1324.         else
  1325.             sRC = ((LPLIBRESET)*lpfnLibReset) (i, lpfnTokenFuncCallback);
  1326.         if (sRC) break;
  1327.     }    
  1328.     if (sRC) {
  1329.        PrintError (hWnd, 0, ERR_BAD_LIB_LOAD, TRUE);
  1330.        return 0;
  1331.     }
  1332.     // Load file
  1333.     hcurSave = SetCursor (LoadCursor (NULL, IDC_WAIT));
  1334.     sRC = LoadProgram (hWnd, &hFileBuff, (LPLINETOKEN) lpbTokLine, (UINT)TOKBUFFSIZE);
  1335.     SetCursor (hcurSave);
  1336.    return sRC;
  1337. }   
  1338.  
  1339. //------------------------------------------------------------
  1340. // LoadProgram - Loads a program
  1341. //------------------------------------------------------------ 
  1342. INT LoadProgram (HWND hWnd, HANDLE *hFileBuff, LPLINETOKEN pltProg, UINT wProgMax) {
  1343.    INT            i, sRC = 0, sErrCnt;
  1344.    LPLINETOKEN    pltLine, pltOld;
  1345.     char            chChar;
  1346.    LPSTR            lpszSource;
  1347.    LPSTR            lpszLineStart;
  1348.  
  1349.     // Load file
  1350.     if (szCmdBuff[0] == '\0') {
  1351.        bHold = TRUE;
  1352.        return 0;
  1353.     }   
  1354.     sRC = ReadFile (szCmdBuff, hFileBuff);
  1355.     if (sRC)    {
  1356.        szCmdBuff[0] = 0;
  1357.         return sRC;
  1358.     }
  1359.     pltLine = pltProg;
  1360.     lpszSource = (LPSTR) GlobalLock (*hFileBuff);
  1361.     if (lpszSource == 0)
  1362.        return ERR_MEM_LOCK;
  1363.  
  1364.     SendDlgItemMessage (hWnd, IDD_LINELIST, LB_RESETCONTENT, 0, 0L);
  1365.     i = 0;
  1366.     sErrCnt = 0;
  1367.     while (*lpszSource != 0) {
  1368.        pltOld = pltLine;
  1369.        lpszLineStart = lpszSource;
  1370.        sRC = TokenizeLine (&lpszSource, &pltLine, i++);
  1371.        if (sRC) {
  1372.           sErrCnt++;
  1373.           if (sErrCnt > 100) {
  1374.              sRC = 0;
  1375.              break;
  1376.           }   
  1377.           PrintError (hWnd, i, sRC, FALSE);
  1378.           sRC = 0;
  1379.         }
  1380.         chChar = *lpszSource;
  1381.         *lpszSource = 0;
  1382.         SendDlgItemMessage (hWnd, IDD_LINELIST, LB_ADDSTRING, 0, 
  1383.                                      (LPARAM) lpszLineStart);
  1384.         *lpszSource = chChar;
  1385.         if ((UINT)(((LPBYTE)pltLine-lpbTokLine) + MAXLINELEN) >= (UINT) TOKBUFFSIZE) {
  1386.           PrintError (hWnd, i, ERR_FILE_TOO_COMPLEX, FALSE);
  1387.          sRC = ERR_FILE_TOO_COMPLEX;
  1388.            break;
  1389.         }
  1390.        if (*lpszSource != 0) lpszSource++;
  1391.     }
  1392.     pltLine->ucLen = 2;
  1393.     pltLine->ucType = TTYPE_EOF;
  1394.     
  1395.     if (strrchr (szCmdBuff, '\\') != 0)
  1396.        strcpy (szProgName, strrchr (szCmdBuff, '\\')+1);
  1397.     else if (strlen (szCmdBuff) < sizeof (szProgName) - 1)
  1398.        strcpy (szProgName, szCmdBuff);
  1399.  
  1400.     if (strrchr (szProgName, '.') != 0)
  1401.         *strrchr (szProgName, '.') = 0;
  1402.  
  1403.     SetWindowText (hMain, szProgName);
  1404.     bRunning = FALSE;
  1405.     bAtEnd = FALSE;
  1406.     wCurrentLine = 0;
  1407.     PostMessage (hMain, MYMSG_REFRESH, 0, 0);
  1408.    return sRC;
  1409.  
  1410. }
  1411. //------------------------------------------------------------
  1412. // TermInterpeter - Terminates the interpeter 
  1413. //------------------------------------------------------------ 
  1414. INT TermInterpeter (void) {
  1415.    INT    i;
  1416.  
  1417.     for (i = 0; i < sLibCount; i++)
  1418.        FreeLibrary (hLib[i]);
  1419.  
  1420.     LocalUnlock (hVarBuff);
  1421.     LocalFree (hVarBuff);
  1422.     GlobalUnlock (hTokBuff);
  1423.     GlobalFree (hTokBuff);
  1424.     
  1425.    return 0;
  1426. }   
  1427. //------------------------------------------------------------
  1428. // ParseCmdLine - Parses the command line
  1429. //------------------------------------------------------------ 
  1430. INT ParseCmdLine (LPSTR lpCmdLine) {
  1431.     INT    i, sRC = 0;
  1432.     
  1433.     // Parse Command line switches        
  1434.     while ((*lpCmdLine == '/') || (*lpCmdLine == '-')) {
  1435.        lpCmdLine++;
  1436.         switch (*lpCmdLine) {
  1437.            case 'l':
  1438.            case 'L':
  1439.                bAutoStart = TRUE;
  1440.                break;
  1441.            default:
  1442.                return ERR_UNKNOWN_CMDSWITCH;
  1443.         }
  1444.         do {
  1445.            lpCmdLine++;       
  1446.         } while ((*lpCmdLine != '\0') && (*lpCmdLine <= ' '));
  1447.     }
  1448.     if (*lpCmdLine == 0) return 0;
  1449.     // Copy filename
  1450.    i = 0;
  1451.     while ((*lpCmdLine != 0) && (i < sizeof (szCmdBuff))) {
  1452.         while ((*lpCmdLine != 0) && (*lpCmdLine > ' ') &&
  1453.                 (*lpCmdLine != '/')) 
  1454.             szCmdBuff[i++] = *lpCmdLine++;
  1455.         
  1456.         szCmdBuff[i++] = 0;
  1457.         while ((*lpCmdLine != 0) && (*lpCmdLine <= ' '))
  1458.             *lpCmdLine++;        
  1459.     }                                   
  1460.     szCmdBuff[i++] = 0;
  1461.     strupr (szCmdBuff);  //Will only cap filename
  1462.     if (bAutoStart == FALSE)
  1463.         bAutoStart = TRUE;
  1464.     else
  1465.        bAutoStart = FALSE;
  1466.     return 0;
  1467. }
  1468. //------------------------------------------------------------
  1469. // AddString - Adds a string to the string list
  1470. //------------------------------------------------------------
  1471. PBYTE AddString (LPSTR lpszString, char *pszPtr, UINT wDLen, INT *sRC) {
  1472.    UINT    wLen, i;
  1473.    PITEM    piItem;
  1474.    LPSTR    lpszPtr;
  1475.    
  1476.     if (wDLen == 0)
  1477.         wLen = lstrlen (lpszString);
  1478.     else
  1479.         wLen = wDLen;
  1480.                         
  1481.     //If adding a null string, Don't add to string list
  1482.     if (wLen == 0)
  1483.        return (PBYTE) szNull;
  1484.     //See if we have the room
  1485.     if (pbVarStrings + wLen + 5 >= (PBYTE) ptVarList) {
  1486.         *sRC = ERR_NO_TOKEN_SPACE;
  1487.         return 0;
  1488.     }
  1489.     piItem = (PITEM) pbVarStrings;
  1490.     piItem->wLen = wLen + 5;
  1491.     piItem->wLinkBack = (WORD) pszPtr;
  1492.     lpszPtr = piItem->szStr;
  1493.     for (i=0; i < wLen; i++)
  1494.         *lpszPtr++ = *lpszString++;
  1495.     *lpszPtr++ = 0;
  1496.  
  1497.     pbVarStrings = (PBYTE) OFFSETOF (lpszPtr);
  1498.     return (PBYTE) piItem->szStr;
  1499. }   
  1500.    
  1501. //------------------------------------------------------------
  1502. // AppendString - Adds a string to the end of a string
  1503. //------------------------------------------------------------
  1504. INT AppendString (PTOKEN ptToken, char *szString) {
  1505.    INT    sLen, sLen1;
  1506.    PITEM    piItem;
  1507.  
  1508.     sLen = strlen ((char *)ptToken->dwData);
  1509.     sLen1 = strlen (szString);
  1510.     if (pbVarStrings + sLen + sLen1 + 5 >= (PBYTE) ptVarList)
  1511.         return ERR_NO_TOKEN_SPACE;
  1512.  
  1513.     piItem = (PITEM) pbVarStrings;
  1514.     piItem->wLen = sLen + sLen1 + 5;
  1515.     piItem->wLinkBack = (WORD) ptToken->dwData;
  1516.     strcpy (piItem->szStr, (char *)ptToken->dwData);
  1517.     strcat (piItem->szStr+sLen, szString);
  1518.     pbVarStrings += sLen + sLen1 + 5;
  1519.     ptToken->dwData = (DWORD)(LPSTR) piItem->szStr;
  1520.     return 0;
  1521. }   
  1522.    
  1523. //------------------------------------------------------------
  1524. // DeleteString - Deletes a string to the string list
  1525. //------------------------------------------------------------
  1526. INT DeleteString (char *szString, WORD wLinkBack) {
  1527.     PITEM piItem, piNext;
  1528.     PBYTE    pbSrc, pbDest;
  1529.     DWORD    *pdwData;
  1530.     UINT    i, wLen;
  1531.  
  1532.     if (szString == 0) return 0;
  1533.     if (szString == szNull) return 0;
  1534.     piItem = (PITEM) (szString-4);
  1535.     if (piItem->wLinkBack == wLinkBack)
  1536.             piItem->wLinkBack = 0xffff;
  1537.  
  1538.     // Compress String list
  1539.     piNext = piItem;
  1540.     while ((PBYTE) piNext < pbVarStrings) {
  1541.         do {
  1542.             (PBYTE) piNext += piNext->wLen;
  1543.        } while (((PBYTE) piNext < pbVarStrings) && (piNext->wLinkBack == 0xffff));
  1544.  
  1545.         if ((PBYTE) piNext >= pbVarStrings)
  1546.             pbVarStrings = (PBYTE) piItem;
  1547.         else {
  1548.            pbSrc = (PBYTE) piNext;
  1549.            pbDest = (PBYTE) piItem;
  1550.  
  1551.            wLen = piNext->wLen;
  1552.            for (i = 0; i < wLen; i++)
  1553.               *pbDest++ = *pbSrc++;
  1554.            pdwData = (DWORD *) piItem->wLinkBack;
  1555.            *pdwData = (DWORD)(LPSTR) &piItem->szStr;
  1556.  
  1557.            if (pbSrc == pbVarStrings)
  1558.               pbVarStrings = pbDest;
  1559.  
  1560.            piItem = (PITEM) pbDest;
  1561.            piNext = (PITEM) pbSrc;
  1562.         }
  1563.     }
  1564.    return 0;
  1565. }   
  1566.  
  1567. //------------------------------------------------------------
  1568. // AddTokenL - Adds a token to the token list
  1569. // This routine allows for a FAR pointer to the name.
  1570. //------------------------------------------------------------ 
  1571. PTOKEN AddTokenL (LPSTR lpszName, BYTE ucType, UINT wData, DWORD dwData, LPINT sRC) {
  1572.    char    szBuff[MAXSTRLEN+1];
  1573.     INT    sLocRC = 0;
  1574.     PTOKEN    ptRet;
  1575.     
  1576.     lstrcpy (szBuff, lpszName);
  1577.     ptRet = AddToken (szBuff, ucType, wData, dwData, &sLocRC);
  1578.     *sRC = sLocRC;
  1579.     return ptRet;
  1580. }   
  1581.  
  1582. //------------------------------------------------------------
  1583. // AddTokenInit - Special version of Add Token that saves
  1584. // space when adding statement and operator tokens.
  1585. //------------------------------------------------------------ 
  1586. INT AddTokenInit (char *szName, BYTE ucType, UINT wData, DWORD dwData) {
  1587.  
  1588.     ptVarList--;  //Make room for new token
  1589.     //See if out of space
  1590.     if ((PBYTE) ptVarList <= pbVarStrings) {
  1591.         ptVarList++;
  1592.         return ERR_NO_TOKEN_SPACE;
  1593.         return 0;
  1594.     }
  1595.       wVarCount++; //Inc token count
  1596.            
  1597.     ptVarList->pszName = szName;
  1598.    ptVarList->ucNameLen = (BYTE) strlen (szName);
  1599.    ptVarList->ucType = ucType;
  1600.     ptVarList->wData = wData;
  1601.     ptVarList->dwData = dwData;
  1602.     return 0;
  1603. }   
  1604. //------------------------------------------------------------
  1605. // AddToken - Adds a token to the token list
  1606. // If the name ptr = 0, a temporary token is added to the list
  1607. //------------------------------------------------------------ 
  1608. PTOKEN AddToken (char *szName, BYTE ucType, UINT wData, DWORD dwData, INT *sRC) {
  1609.     INT    i;
  1610.     PSTR    pszTemp;
  1611.     //Check to see if name too long
  1612.     if (szName != 0) {
  1613.         i = strlen (szName);
  1614.         if (i > MAXSTRLEN) {
  1615.             *sRC = ERR_NAME_TOO_LONG;
  1616.             return 0;
  1617.         }
  1618.     } else
  1619.        i = 0;
  1620.     ptVarList--;  //Make room for new token
  1621.     //See if out of space
  1622.     if ((PBYTE) ptVarList <= pbVarStrings) {
  1623.         ptVarList++;
  1624.         *sRC = ERR_NO_TOKEN_SPACE;
  1625.         return 0;
  1626.     }
  1627.       wVarCount++; //Inc token count
  1628.       // Add Name to string list
  1629.       if (szName != 0) {
  1630.         pszTemp = AddString ((LPSTR)szName, (char *)&ptVarList->pszName, 0, sRC);
  1631.         if (*sRC) {
  1632.             wVarCount--;
  1633.             ptVarList++;
  1634.             return 0;
  1635.         }
  1636.     } else 
  1637.        pszTemp = szNull;
  1638.        
  1639.     ptVarList->pszName = pszTemp;
  1640.    ptVarList->ucNameLen = (BYTE) i;
  1641.    ptVarList->ucType = ucType;
  1642.     ptVarList->wData = wData;
  1643.     ptVarList->dwData = dwData;
  1644.       
  1645.     if ((ucType == TTYPE_STR) || (ucType == TTYPE_DATA)) {
  1646.        if (dwData != 0) {
  1647.             if (ucType == TTYPE_STR)
  1648.                 ptVarList->dwData = (DWORD)(LPSTR) AddString ((LPSTR) dwData, 
  1649.                                                (char *)&ptVarList->dwData, 0, sRC);
  1650.             else                                               
  1651.                 ptVarList->dwData = (DWORD)(LPSTR) AddString ((LPSTR) dwData, 
  1652.                                                (char *)&ptVarList->dwData, wData, sRC);
  1653.             if (*sRC) {
  1654.                if (ptVarList->ucNameLen)
  1655.                    DeleteString (ptVarList->pszName, (WORD)&ptVarList->pszName);
  1656.                 wVarCount--;
  1657.                 ptVarList++;
  1658.                 return 0;
  1659.             }    
  1660.         }
  1661.     }    
  1662.     return ptVarList;
  1663. }   
  1664. //------------------------------------------------------------
  1665. // FindToken - Finds a token in the token list
  1666. //------------------------------------------------------------ 
  1667. PTOKEN FindToken (LPSTR lpszTokenName, INT sNameLen) {
  1668.     UINT        i;
  1669.     char        chChar;
  1670.    PTOKEN    ptList;
  1671.    BOOL        bFound = FALSE;
  1672.  
  1673.     if (sNameLen > 255) return 0;
  1674.     ptList = ptVarList;
  1675.  
  1676.     if (sNameLen == 0) {
  1677.         for (i = 0; i < wVarCount; i++) {
  1678.           if ((WORD)ptList->pszName == (WORD)OFFSETOF (lpszTokenName)) {
  1679.              bFound = TRUE;
  1680.              break;
  1681.           }
  1682.        }
  1683.        ptList++;
  1684.     } else {
  1685.        chChar = *(lpszTokenName+sNameLen);
  1686.        *(lpszTokenName+sNameLen) = 0;
  1687.         for (i = 0; i < wVarCount; i++) {
  1688.            if ((INT) ptList->ucNameLen == sNameLen) {
  1689.               if (lstrcmp (ptList->pszName, lpszTokenName) == 0) {
  1690.                  bFound = TRUE;
  1691.                  break;
  1692.               }
  1693.            }
  1694.            ptList++;
  1695.         }
  1696.        *(lpszTokenName+sNameLen) = chChar;
  1697.     }    
  1698.     if (bFound)
  1699.        return ptList;
  1700.     else
  1701.        return 0;
  1702. }    
  1703.  
  1704. //------------------------------------------------------------
  1705. // FindTokenByType - Finds the most recient token of a given type
  1706. //------------------------------------------------------------ 
  1707. PTOKEN FindTokenByType (BYTE ucType) {
  1708.    PTOKEN    ptList;
  1709.    BOOL        bFound = FALSE;
  1710.    UINT      i;
  1711.  
  1712.     ptList = ptVarList;
  1713.     for (i = 0; i < wVarCount; i++) {
  1714.          if (ptList->ucType == ucType) {
  1715.              bFound = TRUE;
  1716.              break;
  1717.        }
  1718.        ptList++;
  1719.     } 
  1720.     if (bFound)
  1721.        return ptList;
  1722.     else
  1723.        return 0;
  1724. }    
  1725.  
  1726. //------------------------------------------------------------
  1727. // TokFuncCallback - External entry point
  1728. //------------------------------------------------------------ 
  1729. DWORD CALLBACK TokFuncCallback (INT sFunction, LPTOKEN lptDest, 
  1730.                LPSTR lpszName, BYTE ucNewType, UINT wData, DWORD dwData) {
  1731.     INT    sRC = 0;
  1732.     PTOKEN    ptDest;
  1733.     
  1734.     ptDest = (PTOKEN)LOWORD(lptDest);
  1735.     switch (sFunction) {
  1736.        case CBF_ADDTOKEN:
  1737.             AddTokenL (lpszName, ucNewType, wData, dwData, &sRC);
  1738.             return (DWORD) sRC;
  1739.  
  1740.        case CBF_FINDTOKEN:
  1741.             return (DWORD) (LPTOKEN) FindToken (lpszName, wData);
  1742.  
  1743.        case CBF_SETTOKEN:
  1744.             return (DWORD) SetToken (ptDest, ucNewType, wData, dwData);
  1745.  
  1746.        case CBF_GETTOKENVAL:
  1747.             return GetTokenVal (ptDest);
  1748.  
  1749.        case CBF_GETTOKENSTRING:
  1750.             return (DWORD) GetTokenStringL (ptDest);
  1751.  
  1752.        case CBF_RESOLVELINE:
  1753.             return (DWORD) ResolveLine ((LPLINETOKEN *)dwData, lpszName, wData);
  1754.  
  1755.         default:
  1756.             return ERR_BAD_FUNC;
  1757.     }        
  1758. }
  1759. //------------------------------------------------------------
  1760. // SetToken - Sets a token to a new value
  1761. //------------------------------------------------------------ 
  1762. INT SetToken (PTOKEN ptDest, BYTE ucNewType, UINT wData, DWORD dwData) {
  1763.    INT    sRC = 0;
  1764.  
  1765.     if ((ptDest->ucType != TTYPE_NUM) && (ptDest->ucType != TTYPE_STR) &&
  1766.         (ptDest->ucType != TTYPE_DATA))
  1767.        return ERR_ILLEGAL_ASSIGNMENT;
  1768.  
  1769.     if ((ptDest->ucType != TTYPE_NUM) &&
  1770.         ((char *)ptDest->dwData != ptDest->pszName))
  1771.         DeleteString ((char *)ptDest->dwData, (WORD) &ptDest->dwData);
  1772.  
  1773.     ptDest->ucType = ucNewType;
  1774.     ptDest->wData = wData;
  1775.     ptDest->dwData = dwData;
  1776.  
  1777.     if ((ucNewType == TTYPE_STR) || (ucNewType == TTYPE_DATA)) {
  1778.         if (ucNewType == TTYPE_STR)
  1779.             ptDest->dwData = (DWORD)(LPSTR) AddString ((LPSTR) dwData, 
  1780.                                         (char *)&ptDest->dwData, 0, &sRC);
  1781.         else                                               
  1782.             ptDest->dwData = (DWORD)(LPSTR) AddString ((LPSTR) dwData, 
  1783.                                         (char *)&ptDest->dwData, wData, &sRC);
  1784.     }                                        
  1785.     if (sRC) 
  1786.        ptDest->dwData = (DWORD)(LPSTR) ptDest->pszName;
  1787.     return sRC;
  1788. }    
  1789.  
  1790. //------------------------------------------------------------
  1791. // DeleteToken - Deltes a token in the token list
  1792. //------------------------------------------------------------ 
  1793. INT DeleteToken (PTOKEN ptToken) {
  1794.  
  1795.     if (ptToken->ucNameLen != 0) 
  1796.        DeleteString (ptToken->pszName, (WORD)&ptToken->pszName);
  1797.  
  1798.     if (((ptToken->ucType == TTYPE_STR) || (ptToken->ucType == TTYPE_DATA)) &&
  1799.          ((char *)ptToken->dwData != ptToken->pszName))
  1800.         DeleteString ((char *)ptToken->dwData, (WORD)&ptToken->dwData);
  1801.     
  1802.     if (ptToken == ptVarList) {
  1803.        ptVarList++;
  1804.         wVarCount--;
  1805.     } else    
  1806.         ptToken->ucType = TTYPE_DEL;
  1807.    return 0;
  1808. }    
  1809. //------------------------------------------------------------
  1810. // GetTokenStringL - Returns a pointer to the string value
  1811. // for a token.
  1812. //------------------------------------------------------------ 
  1813. LPSTR GetTokenStringL (PTOKEN ptDest) {
  1814.   
  1815.    switch (ptDest->ucType) {
  1816.       case TTYPE_NUM:
  1817.              ltoa (ptDest->dwData, szTemp, 10);
  1818.              return (LPSTR) szTemp;
  1819.             
  1820.         case TTYPE_DATA:
  1821.         case TTYPE_STR:
  1822.             if (ptDest->dwData != 0)
  1823.                return (LPSTR) ptDest->dwData;
  1824.             //If no string, fall through to default code
  1825.       default:
  1826.           if (ptDest->ucNameLen == 0) {
  1827.              szTemp[0] = 0;
  1828.                 return (LPSTR)szTemp;
  1829.             } else                 
  1830.                return (LPSTR) ptDest->pszName;
  1831.     }
  1832. }      
  1833. //------------------------------------------------------------
  1834. // GetTokenString - Returns a pointer to the string value
  1835. // for a token.
  1836. //------------------------------------------------------------ 
  1837. char *GetTokenString (PTOKEN ptDest) {
  1838.   
  1839.    switch (ptDest->ucType) {
  1840.       case TTYPE_NUM:
  1841.              ltoa (ptDest->dwData, szTemp, 10);
  1842.              return szTemp;
  1843.             
  1844.         case TTYPE_DATA:
  1845.         case TTYPE_STR:
  1846.             if (ptDest->dwData != 0)
  1847.                return (char *) ptDest->dwData;
  1848.             //If no string, fall through to default code
  1849.       default:
  1850.           if (ptDest->ucNameLen == 0) {
  1851.              szTemp[0] = 0;
  1852.                 return szTemp;
  1853.             } else                 
  1854.                return ptDest->pszName;
  1855.     }
  1856. }      
  1857. //------------------------------------------------------------
  1858. // GetTokenVal - Returns a pointer to the numberic value
  1859. // for a token.
  1860. //------------------------------------------------------------ 
  1861. LONG GetTokenVal (PTOKEN ptDest) {
  1862.   
  1863.     if (ptDest->ucType == TTYPE_NUM)
  1864.          return ptDest->dwData;
  1865.     else
  1866.         return atol ((char *)GetTokenString (ptDest));
  1867. }      
  1868.  
  1869. //------------------------------------------------------------
  1870. // FindChar - finds the next non-space character
  1871. //------------------------------------------------------------ 
  1872. LPSTR FindChar (LPSTR lpszLine) {
  1873.  
  1874.    while (*lpszLine != '\0') {
  1875.       if (*lpszLine == '\n') {
  1876.          break;
  1877.       }   
  1878.       if (*lpszLine == 0x0d) {
  1879.          *lpszLine = ' ';
  1880.       }   
  1881.       if (*lpszLine > ' ') break;
  1882.       lpszLine++;
  1883.    }
  1884.    return lpszLine;   
  1885. }   
  1886.  
  1887. //------------------------------------------------------------
  1888. // UCaseLine - Converts line to uppercase.
  1889. //------------------------------------------------------------ 
  1890. void UCaseLine (LPSTR lpszLine) {
  1891.     BOOL    bInQuote = FALSE;
  1892.  
  1893.    while (*lpszLine != '\0' && *lpszLine != '\n') {
  1894.       if (!bInQuote) {
  1895.          if (*lpszLine >= 'a' && *lpszLine <= 'z')
  1896.              *lpszLine = *lpszLine & (char) 0xdf;
  1897.         }
  1898.         if (*lpszLine == '"')
  1899.            bInQuote = !bInQuote;
  1900.         lpszLine++;    
  1901.     }
  1902.     return;
  1903. }    
  1904. //------------------------------------------------------------
  1905. // ComputeNum - Converts token to number
  1906. //------------------------------------------------------------ 
  1907. LONG ComputeNum (LPSTR *lpszLine, INT *sRC) {
  1908.    LONG lNum = 0, lTemp, lOld;
  1909.    INT    sBase = 10;
  1910.    BYTE    ucChar;
  1911.  
  1912.     if (**lpszLine == '0')
  1913.         switch (*(*lpszLine+1)) {
  1914.             case 'X':
  1915.                sBase = 16;
  1916.                (*lpszLine) += 2;
  1917.                break;
  1918.             case 'O':
  1919.                 sBase = 8;
  1920.                (*lpszLine) += 2;
  1921.                 break;
  1922.             case 'B':
  1923.                 sBase = 2;
  1924.                (*lpszLine) += 2;
  1925.                 break;
  1926.             default:
  1927.                 sBase = 10;
  1928.         }                   
  1929.     ucChar = **lpszLine;           
  1930.       while ((ucChar >= '0' && ucChar <= '9') ||
  1931.              ((ucChar >= 'A' && ucChar <= 'F') && sBase == 16)) {
  1932.         if (ucChar <= '9')
  1933.             lTemp = (LONG) ucChar - '0';
  1934.         else
  1935.             lTemp = (LONG) (ucChar - 'A' + 10);
  1936.         if (lTemp >= sBase)
  1937.             break;
  1938.         lOld = lNum;
  1939.        lNum = (lNum * sBase) + lTemp;
  1940.        (*lpszLine)++;
  1941.        ucChar = **lpszLine;
  1942.        if (sBase == 10) {
  1943.            if (lOld > lNum) {
  1944.               *sRC = ERR_OVERFLOW;
  1945.               break;
  1946.            }   
  1947.        } else {
  1948.            if ((DWORD) lOld > (DWORD) lNum) {
  1949.               *sRC = ERR_OVERFLOW;
  1950.               break;
  1951.            }
  1952.        }    
  1953.       }
  1954.       return lNum;
  1955. }      
  1956.  
  1957. //------------------------------------------------------------
  1958. // TokenizeLine - Tokenizes the line.
  1959. //------------------------------------------------------------ 
  1960. INT TokenizeLine (LPSTR *plpszLineIn, LPLINETOKEN *ppbTokOut, UINT wLineNum) {
  1961.     LPSTR                lpszLine;
  1962.     LPSTR                lpszTokStart;
  1963.     LONG                lNum;
  1964.     char                chChar;
  1965.     BYTE                ucNameLen;
  1966.     INT                sRC = 0;
  1967.     LPLINETOKEN        pltOut;
  1968.     LPLINESTARTTOK    plstStart;
  1969.    PTOKEN            ptOldTok;
  1970.  
  1971.     lpszLine = *plpszLineIn;
  1972.     pltOut = *ppbTokOut;
  1973.  
  1974.     plstStart = (LPLINESTARTTOK) pltOut;
  1975.     plstStart->ucLen = 6;
  1976.     plstStart->ucType = TTYPE_LINE;
  1977.     plstStart->wLineNum = wLineNum;
  1978.     (PBYTE) pltOut += 6;
  1979.  
  1980.     UCaseLine (lpszLine);
  1981.     lpszLine = FindChar (lpszLine);
  1982.  
  1983.     while ((*lpszLine != '\n') && (*lpszLine != '\0') && (sRC == 0)) {
  1984.         lpszTokStart = lpszLine;
  1985.         ucNameLen = 0;
  1986.         //Check for number
  1987.         if ((*lpszTokStart >= '0') && (*lpszTokStart <= '9')) {
  1988.             lNum = ComputeNum (&lpszLine, &sRC);
  1989.             if (sRC) break;
  1990.             if ((lNum > 32767) || (lNum < -32767)) {
  1991.                 pltOut->ucType = TTYPE_LCONST;
  1992.                 pltOut->ucLen = 6;
  1993.                 ((LPVARLCONST) pltOut)->lData = lNum;
  1994.                 (PBYTE) pltOut += 6;
  1995.             } else {
  1996.                 pltOut->ucType = TTYPE_SCONST;
  1997.                 pltOut->ucLen = 4;
  1998.                 ((LPVARSCONST) pltOut)->sData = (INT) lNum;
  1999.                 (PBYTE) pltOut += 4;
  2000.             }
  2001.         //check for quoted string
  2002.         } else if (*lpszTokStart == '"') {
  2003.            lpszLine++;
  2004.            lpszTokStart++;
  2005.             do {
  2006.                 ucNameLen++;
  2007.                 lpszLine++;
  2008.             } while ((*lpszLine != '\n') && (*lpszLine != '\0') &&
  2009.                      (*lpszLine != '"') && (ucNameLen < MAXSTRLEN));
  2010.             if (*lpszLine == '"') {
  2011.                 pltOut->ucType = TTYPE_STRCONST;
  2012.                 pltOut->ucLen = (BYTE) (ucNameLen + 3);
  2013.                 chChar = *lpszLine;
  2014.                 *lpszLine = '\0';
  2015.                 lstrcpy ((LPSTR) &pltOut->ptToken, lpszTokStart);
  2016.                 *lpszLine = chChar;
  2017.                 (PBYTE) pltOut += ucNameLen + 3;
  2018.                lpszLine++;
  2019.             } else
  2020.                 sRC = ERR_NO_END_QUOTE;
  2021.         //Otherwise it can be tokenized    
  2022.         } else {
  2023.            //See if allowable variable
  2024.             if (((*lpszTokStart >= 'A') && (*lpszTokStart <= 'Z')) ||
  2025.                  (*lpszTokStart == '_')                            ) {
  2026.                 do {
  2027.                     ucNameLen++;
  2028.                     lpszLine++;
  2029.                 } while ((ucNameLen < MAXSTRLEN                    )  &&
  2030.                          (((*lpszLine >= 'A') && (*lpszLine <= 'Z'))  ||
  2031.                            ((*lpszLine >= '0') && (*lpszLine <= '9'))  ||
  2032.                           (*lpszLine == '_') ||  (*lpszLine == '.')   ||
  2033.                            (*lpszLine == '$') ));
  2034.            //Must be operator, or other string constant
  2035.             } else {
  2036.                 do {
  2037.                     ucNameLen++;
  2038.                     lpszLine++;
  2039.                 } while ((ucNameLen < 2)                           &&
  2040.                          (*lpszLine != '_')                        &&
  2041.                          (((*lpszLine > ' ') && (*lpszLine < '0')) ||
  2042.                            ((*lpszLine > '9') && (*lpszLine < 'A')) ||
  2043.                           (*lpszLine > 'Z')                      ));
  2044.                           
  2045.                 ptOldTok = FindToken (lpszTokStart, 2);
  2046.                 if ((ptOldTok == 0) && (ucNameLen == 2)) {
  2047.                    ucNameLen = 1;
  2048.                    lpszLine--;
  2049.                 }   
  2050.             }
  2051.             ptOldTok = FindToken (lpszTokStart, ucNameLen);
  2052.             if (ptOldTok == 0) {
  2053.                chChar = *lpszLine;
  2054.                *lpszLine = 0;
  2055.                 if (*lpszLine == ':') 
  2056.                    ptOldTok = AddTokenL (lpszTokStart, TTYPE_LABEL, 0, 
  2057.                                          (DWORD)(LPVOID)pltOut, &sRC);
  2058.                 else
  2059.                    ptOldTok = AddTokenL (lpszTokStart, TTYPE_STR, 0, 0, &sRC);
  2060.                 *lpszLine = chChar;
  2061.                 pltOut->ucType = TTYPE_VAR;
  2062.             } else {
  2063.                // If comment, skip to end of line
  2064.                 if (ptOldTok->ucType == TTYPE_CMT2EOL) {
  2065.                     while ((*lpszLine != '\n') && (*lpszLine != '\0')) {
  2066.                        if (*lpszLine == 0x0d)
  2067.                           *lpszLine = ' ';
  2068.                         lpszLine++;
  2069.                     }    
  2070.                    break;
  2071.                 }   
  2072.                 switch (ptOldTok->ucType) {
  2073.                     case TTYPE_NUM:
  2074.                     case TTYPE_STR:
  2075.                         if (*lpszLine == ':') {
  2076.                             ptOldTok->ucType = TTYPE_LABEL;
  2077.                             ptOldTok->dwData = (DWORD)(LPVOID)pltOut;
  2078.                         } else
  2079.                             pltOut->ucType = TTYPE_VAR;
  2080.                        break;
  2081.                     case TTYPE_LABEL:
  2082.                         if (*lpszLine == ':') 
  2083.                            sRC = ERR_MULTI_DEF_LABEL;
  2084.                         break;
  2085.                     default:
  2086.                         pltOut->ucType = ptOldTok->ucType;
  2087.                 }        
  2088.             } 
  2089.             if (*lpszLine == ':') 
  2090.                lpszLine++;
  2091.             else {
  2092.                pltOut->ucLen = 4;
  2093.                 pltOut->ptToken = ptOldTok;
  2094.                (PBYTE) pltOut += 4;
  2095.             }   
  2096.         }            
  2097.         lpszLine = FindChar (lpszLine);
  2098.     }
  2099.  
  2100.    if ((*lpszLine != '\n') || (*lpszLine != '\0')) 
  2101.        while ((*lpszLine != '\n') && (*lpszLine != '\0')) 
  2102.           lpszLine++;
  2103.  
  2104.     pltOut->ucLen = 2;
  2105.     pltOut->ucType = TTYPE_EOL;
  2106.    (PBYTE) pltOut += 2;
  2107.  
  2108.     plstStart->wLineLen = (LPBYTE) pltOut - (LPBYTE) plstStart;
  2109.  
  2110.     *plpszLineIn = lpszLine;
  2111.     *ppbTokOut = pltOut;
  2112.  
  2113.     return sRC;
  2114. }    
  2115. //------------------------------------------------------------
  2116. // ResolveLine - Converts line tokens to text
  2117. //------------------------------------------------------------ 
  2118. INT ResolveLine (LPLINETOKEN *pltCurrToken, LPSTR lpszOutput, INT sMaxSize) {
  2119.    PTOKEN ptTemp;
  2120.    INT    sRC = 0;
  2121.  
  2122.     *lpszOutput = '\0';
  2123.     while ((*pltCurrToken)->ucType != TTYPE_EOL) {
  2124.         ptTemp = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
  2125.         if (sRC) break;
  2126.         sRC = Eval (pltCurrToken, ptTemp, FUNC_EXECUTE);
  2127.         if (sRC) {
  2128.             DeleteToken (ptTemp);
  2129.             break;
  2130.         }
  2131.         lstrcat (lpszOutput, GetTokenStringL (ptTemp));
  2132.         DeleteToken (ptTemp);
  2133.         lstrcat (lpszOutput, " ");
  2134.     }    
  2135.     return sRC;
  2136. }
  2137.  
  2138. //------------------------------------------------------------
  2139. // SkipLine - Scan until start of next line
  2140. //------------------------------------------------------------ 
  2141. LONG SkipLine (LPLINETOKEN *pltStart) {
  2142.  
  2143.    while ((*pltStart)->ucType != TTYPE_EOL)
  2144.         *(PWORD)pltStart += (*pltStart)->ucLen;
  2145.     *(PWORD)pltStart += (*pltStart)->ucLen;
  2146.     return 0;
  2147. }
  2148.  
  2149. //------------------------------------------------------------
  2150. // WriteOutput - Writes a line to the output listbox
  2151. //------------------------------------------------------------ 
  2152. void WriteOutput (HWND hWnd, char *pszOutput) {
  2153.    LONG    index;
  2154.    
  2155.     SendDlgItemMessage (hWnd, IDD_OUTLIST, WM_SETREDRAW, FALSE, 0);
  2156.     if (SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_GETCOUNT, 0, 0) > MAXOUTLINES)
  2157.         SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_DELETESTRING, 0, 0);
  2158.    
  2159.     index = SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_ADDSTRING, 0, 
  2160.                                 (LPARAM)(LPSTR) pszOutput);
  2161.     SendDlgItemMessage (hWnd, IDD_OUTLIST, LB_SETTOPINDEX, (WORD)index, 0);
  2162.     SendDlgItemMessage (hWnd, IDD_OUTLIST, WM_SETREDRAW, TRUE, 0);
  2163.                         
  2164.     if (IsIconic (hWnd)) {
  2165.         bShowOut = TRUE;                            
  2166.         ShowWindow (hWnd, SW_RESTORE);
  2167.     } else if (!bShowOut) {
  2168.        bShowOut = TRUE;
  2169.        PostMessage (hWnd, MYMSG_REFRESH, 0, 0);
  2170.     }
  2171.     bAutoStart = FALSE;
  2172.     return;                        
  2173. }                        
  2174.  
  2175. //------------------------------------------------------------
  2176. // PrintError - Displays an error message on the output listbox
  2177. //------------------------------------------------------------ 
  2178. void PrintError (HWND hWnd, INT sLineNum, INT sErrorCode, BOOL bSetList) {
  2179.    char    szTempStr[MAXLINELEN];
  2180.    char    szErrorStr[50];
  2181.  
  2182.     strcpy (szTempStr, "Error - Line: ");
  2183.     itoa (sLineNum+1, szTemp, 10);
  2184.     strcat (szTempStr, szTemp);
  2185.     strcat (szTempStr, "     ");
  2186.     
  2187.     if (sErrorCode > 0)
  2188.        sErrorCode += 11;
  2189.     else 
  2190.        sErrorCode = abs (sErrorCode);
  2191.     if (LoadString (hInst, sErrorCode, szErrorStr, sizeof (szErrorStr)) == 0) {
  2192.         itoa (sErrorCode, szErrorStr, 10);
  2193.         strcat (szTempStr, "Error number: ");
  2194.     }
  2195.     strcat (szTempStr, szErrorStr);
  2196.     WriteOutput (hWnd, szTempStr);
  2197.     if (bSetList) {
  2198.         bShowList = TRUE;
  2199.         bShowOut = TRUE;
  2200.        PostMessage (hWnd, MYMSG_REFRESH, 0, 0);
  2201.        SetActiveWindow (hWnd);
  2202.     }   
  2203.     return;                        
  2204. }                        
  2205.  
  2206. //----------------------------------------------------------------------
  2207. // Read File - Allocates a buff in global memory and reads in a file
  2208. //----------------------------------------------------------------------
  2209. INT ReadFile (char *szFileName, HANDLE *hFileBuff) {
  2210.    
  2211.     OFSTRUCT    ofFile;
  2212.     HFILE        hFileHandle;
  2213.     UINT        wBytesRead;
  2214.     LPBYTE     lpbFileBuff;
  2215.  
  2216.     if (*hFileBuff != 0)
  2217.        GlobalFree (*hFileBuff);
  2218.     
  2219.     *hFileBuff = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, 65535);
  2220.     
  2221.     if (*hFileBuff == 0) return ERR_OUT_OF_MEMORY;
  2222.     lpbFileBuff = GlobalLock (*hFileBuff);
  2223.  
  2224.     hFileHandle = OpenFile (szFileName, &ofFile, OF_READ);
  2225.     if (hFileHandle == -1) {
  2226.        GlobalUnlock (*hFileBuff);
  2227.        GlobalFree (*hFileBuff);
  2228.        return ERR_FOPEN_ERR - ofFile.nErrCode;
  2229.     }
  2230.     wBytesRead = _lread (hFileHandle, lpbFileBuff, (WORD)65534);
  2231.     _lclose (hFileHandle);
  2232.  
  2233.     if (wBytesRead == 65534) {
  2234.        GlobalUnlock (*hFileBuff);
  2235.        GlobalFree (*hFileBuff);
  2236.        return ERR_FILE_TOO_BIG;
  2237.     }
  2238.     *(lpbFileBuff + wBytesRead) = 0;
  2239.    GlobalUnlock (*hFileBuff);
  2240.    GlobalReAlloc (*hFileBuff, wBytesRead+1, 0);
  2241.    return 0;
  2242. }
  2243. //------------------------------------------------------------
  2244. // StuffVKey - Stuffs a virtual key into the system message 
  2245. // queue.
  2246. //------------------------------------------------------------ 
  2247. void WINAPI Keybd_Event (void);
  2248. void StuffVKey (BYTE ucVKey, BOOL bMake) {
  2249.     WORD    RegAX, RegBX;
  2250.     
  2251.     if (bMake)
  2252.         RegAX = (WORD) ucVKey;
  2253.     else    
  2254.         RegAX = 0x8000 | (WORD) ucVKey;
  2255.     RegBX = (WORD) MapVirtualKey (ucVKey, 0);
  2256.     _asm {
  2257.        mov ax,RegAX
  2258.        mov bx,RegBX
  2259.     }   
  2260.    Keybd_Event();
  2261. }
  2262. //------------------------------------------------------------
  2263. // StuffOneKey - Processes a character in a stuff key string
  2264. //------------------------------------------------------------ 
  2265. INT StuffOneKey (char **pszString) {
  2266.    BYTE    ucVKey, ucShift = 0;
  2267.    INT    sRC = 0, sRepCnt = 0, i;
  2268.    UINT  wKey;
  2269.    BOOL    bFound;
  2270.    char    *pszEnd;
  2271.    char    *pszNum;
  2272.  
  2273.    bFound = FALSE;
  2274.     ucVKey = **pszString;
  2275.     if (ucVKey == 0) return 0;
  2276.     (*pszString)++;
  2277.     switch (ucVKey) {
  2278.        case '+':
  2279.             ucShift = VK_SHIFT;
  2280.             break;
  2281.        case '%':
  2282.             ucShift = VK_MENU;
  2283.             break;
  2284.        case '^':
  2285.             ucShift = VK_CONTROL;
  2286.             break;
  2287.        case '(':
  2288.            sRC = StuffKeyString (pszString);
  2289.            if (sRC == 1)
  2290.               return 0;
  2291.             else if (sRC == 0)
  2292.                return ERR_BAD_SENDKEY_STR;
  2293.             else
  2294.                return sRC;
  2295.        case ')':
  2296.            return 1;
  2297.  
  2298.        case '{':
  2299.            if (*(*pszString+1) == '}') {
  2300.                 ucVKey = **pszString;
  2301.                 (*pszString) += 2;
  2302.             } else {
  2303.                pszEnd = strchr (*pszString, '}');
  2304.                if (pszEnd == 0) return ERR_BAD_SENDKEY_STR;
  2305.                *pszEnd = 0;
  2306.                pszNum = strchr (*pszString, ' ');
  2307.                if (pszNum != 0) *pszNum = 0;
  2308.                 for(i = 0; i < dim(SKList); i++) {
  2309.                     if (strcmpi (SKList[i].szName, *pszString) == 0) {
  2310.                        bFound = TRUE;
  2311.                        break;
  2312.                     }   
  2313.                 }
  2314.                 if (!bFound) return ERR_BAD_SENDKEY_STR;
  2315.                 ucVKey = SKList[i].ucKey;
  2316.                 if (pszNum != 0) {
  2317.                     *pszNum++ = ' ';
  2318.                     (*pszString) = pszNum;
  2319.                     sRepCnt = atoi(pszNum);
  2320.                 }
  2321.                 *pszEnd++ = '}';
  2322.                 (*pszString) = pszEnd;
  2323.             }   
  2324.            break;
  2325.  
  2326.     }
  2327.     if (ucShift) { 
  2328.           StuffVKey (ucShift, TRUE);
  2329.           StuffOneKey (pszString);
  2330.           StuffVKey (ucShift, FALSE);
  2331.     } else {
  2332.        if (!bFound) {
  2333.               wKey = VkKeyScan (ucVKey);
  2334.               ucVKey = (BYTE) wKey;
  2335.           } else wKey = 0;    
  2336.           if (HIBYTE (wKey) == 1) {
  2337.               StuffVKey (VK_SHIFT, TRUE);
  2338.               StuffVKey (ucVKey, TRUE);
  2339.               StuffVKey (ucVKey, FALSE);
  2340.               StuffVKey (VK_SHIFT, FALSE);
  2341.         } else {
  2342.               StuffVKey (ucVKey, TRUE);
  2343.             StuffVKey (ucVKey, FALSE);
  2344.         }       
  2345.     }   
  2346.     return sRC;
  2347. }        
  2348.  
  2349. //------------------------------------------------------------
  2350. // StuffKeyString - Stuffs a 'stuff key' string into the
  2351. // system event queue.
  2352. //------------------------------------------------------------ 
  2353. INT StuffKeyString (char **pszString) {
  2354.    INT    sRC = 0;
  2355.     
  2356.     while ((**pszString != 0) && (sRC == 0)) 
  2357.         sRC = StuffOneKey (pszString);
  2358.     return sRC;
  2359. }        
  2360.  
  2361. //------------------------------------------------------------
  2362. // CallFunc - Calls user defined and built in functions
  2363. //------------------------------------------------------------ 
  2364. INT CallFunc (LPLINETOKEN *pltLine, PTOKEN ptCurrValue, INT sFunc) {
  2365.    LPLINETOKEN    pltFunc;
  2366.    PTOKEN    ptInd;
  2367.    PTOKEN    ptNextValue, ptArg1;
  2368.    INT        sRC = 0, sTokCnt;
  2369.    UINT        wTemp;
  2370.  
  2371.     ptInd = (*pltLine)->ptToken;
  2372.     sTokCnt = (*pltLine)->ucLen;
  2373.     *(PWORD)pltLine += sTokCnt;
  2374.     // If no open paren, just return func name as string
  2375.     if ((*pltLine)->ucType != TTYPE_OPAREN) {
  2376.         ptCurrValue->ucType = TTYPE_STR;
  2377.         ptCurrValue->wData = 0;
  2378.         ptCurrValue->dwData = (DWORD)(LPSTR)ptInd->pszName;
  2379.         return 0;
  2380.     }
  2381.     sTokCnt = (*pltLine)->ucLen;
  2382.     *(PWORD)pltLine += sTokCnt;
  2383.  
  2384.     // Push arguments onto var list
  2385.     ptArg1 = AddToken (0, TTYPE_STR, 0, (DWORD)(LPSTR)ptInd->pszName, &sRC);
  2386.     if (sRC) return sRC;
  2387.     sTokCnt = 1;
  2388.     while (((*pltLine)->ucType != TTYPE_CPAREN) &&
  2389.            ((*pltLine)->ucType != TTYPE_EOL) && (sRC == 0)) {
  2390.         ptNextValue = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
  2391.           sRC = Eval (pltLine, ptNextValue, sFunc);
  2392.           sTokCnt++;
  2393.     }
  2394.     if ((sRC == 0) && (sFunc == FUNC_EXECUTE)) {
  2395.         switch (ptInd->ucType) {
  2396.             case TTYPE_LABEL:
  2397.                 SetToken (ptCurrValue, TTYPE_RETVAL, sTokCnt, (DWORD)(LPTOKEN)ptArg1);
  2398.                 ptCurrValue->ucType = TTYPE_RETVAL;
  2399.                pltFunc = (LPLINETOKEN) ptInd->dwData;
  2400.                wTemp = wCurrentLine;
  2401.                 while (sRC == 0)
  2402.                    sRC = ExecuteLine (&pltFunc, FUNC_EXECUTE);
  2403.                 if (sRC == RC_END_OF_SUB) {
  2404.                     sRC = 0;
  2405.                     wCurrentLine = wTemp;
  2406.                 }   
  2407.                 break;
  2408.             case TTYPE_LOCALFUNC:
  2409.                 SetToken (ptCurrValue, TTYPE_NUM, sTokCnt, (DWORD)(LPTOKEN)ptArg1);
  2410.                 sRC = (*((PFUNCTOK)ptInd)->Fxn)(pltLine, ptCurrValue);
  2411.                 break;
  2412.             case TTYPE_LIBFUNC:
  2413.                 SetToken (ptCurrValue, TTYPE_NUM, sTokCnt, (DWORD)(LPTOKEN)ptArg1);
  2414.                 sRC = ((LPLIBFUNC)*(lpfnLibFunc[HIWORD(ptInd->dwData)]))
  2415.                            (pltLine, (LPTOKEN)ptCurrValue, LOWORD (ptInd->dwData),
  2416.                             lpfnTokenFuncCallback, hMain);
  2417.                 break;
  2418.             default:
  2419.                 sRC = ERR_FUNC_NOT_FOUND;
  2420.                 break;
  2421.  
  2422.         }
  2423.     }    
  2424.     // Remove arg tokens from var list
  2425.     while (--sTokCnt >= 0)
  2426.        DeleteToken (ptArg1-sTokCnt);
  2427.     if (sRC) return sRC;
  2428.     if ((*pltLine)->ucType != TTYPE_CPAREN) 
  2429.        return ERR_NO_CLOSE_PAREN;
  2430.     sTokCnt = (*pltLine)->ucLen;
  2431.     *(PWORD)pltLine += sTokCnt;
  2432.     return sRC;
  2433. }
  2434.  
  2435. //------------------------------------------------------------
  2436. // GetOp - Recursive routine that evaluates an expression
  2437. //------------------------------------------------------------ 
  2438. INT GetOp (LPLINETOKEN *pltLine, PTOKEN ptCurrValue, UINT *wLevel, INT sFunc) {
  2439.    UINT        oldLevel, wNewLev;
  2440.    INT        sRC = 0;
  2441.    BYTE        ucTokLen;
  2442.    POPTOK    potTokIndirect;
  2443.    PTOKEN    ptInd;
  2444.    PTOKEN    ptNextValue;
  2445.  
  2446.     ucTokLen = (*pltLine)->ucLen;
  2447.     switch ((*pltLine)->ucType) {
  2448.         case TTYPE_SCONST:
  2449.             sRC = SetToken (ptCurrValue, TTYPE_NUM, 0,
  2450.                             (DWORD)((LPVARSCONST) *pltLine)->sData);
  2451.             *(PWORD)pltLine += ucTokLen;
  2452.             break;
  2453.  
  2454.         case TTYPE_LCONST:
  2455.             sRC = SetToken (ptCurrValue, TTYPE_NUM, 0,
  2456.                             (DWORD)((LPVARLCONST) *pltLine)->lData);
  2457.             *(PWORD)pltLine += ucTokLen;
  2458.             break;
  2459.  
  2460.         case TTYPE_STRCONST:
  2461.             sRC = SetToken (ptCurrValue, TTYPE_STR, 0,
  2462.                             (DWORD)(LPSTR)((LPSTRCONST)*pltLine)->szData);
  2463.             *(PWORD)pltLine += ucTokLen;
  2464.             break;
  2465.  
  2466.         case TTYPE_VAR:
  2467.             ptInd = (PTOKEN) (*pltLine)->ptToken;
  2468.             switch (ptInd->ucType) {
  2469.                 case TTYPE_LABEL:
  2470.                sRC = CallFunc (pltLine, ptCurrValue, sFunc);
  2471.                break;
  2472.                 case TTYPE_NUM:
  2473.                sRC = SetToken (ptCurrValue, ptInd->ucType, ptInd->wData, 
  2474.                                    GetTokenVal(ptInd));
  2475.                       *(PWORD)pltLine += ucTokLen;
  2476.                    break;
  2477.                 case TTYPE_DATA:
  2478.                 case TTYPE_STR:
  2479.                sRC = SetToken (ptCurrValue, ptInd->ucType, ptInd->wData, 
  2480.                                    (DWORD)GetTokenStringL(ptInd));
  2481.                       *(PWORD)pltLine += ucTokLen;
  2482.                    break;
  2483.                 default:                   
  2484.                    sRC = ERR_SYNTAX;
  2485.                    break;
  2486.             }    
  2487.             break;
  2488.             
  2489.         case TTYPE_OPAREN:              
  2490.               ptInd = (*pltLine)->ptToken;
  2491.               *(PWORD)pltLine += ucTokLen;
  2492.             if (sFunc == FUNC_EXECUTE) {
  2493.                 sRC = (*((PFUNCTOK)ptInd)->Fxn)(pltLine, ptCurrValue);
  2494.             } else {
  2495.                 Eval2Num (pltLine, sFunc, &sRC);
  2496.                 if (sRC) return sRC;
  2497.                 if ((*pltLine)->ucType != TTYPE_CPAREN) 
  2498.                   return ERR_NO_CLOSE_PAREN;
  2499.                else
  2500.                     *(PWORD)pltLine += (*pltLine)->ucLen;
  2501.          }
  2502.             break;
  2503.  
  2504.         case TTYPE_LIBFUNC:
  2505.         case TTYPE_LOCALFUNC:
  2506.            sRC = CallFunc (pltLine, ptCurrValue, sFunc);
  2507.             break;
  2508.  
  2509.         case TTYPE_LUOP:
  2510.               potTokIndirect = (POPTOK) (*pltLine)->ptToken;
  2511.             *(PWORD)pltLine += ucTokLen;
  2512.  
  2513.             //Kluge to allow minus sign to have 2 levels, 13 for
  2514.             //reguar op and 15 for unary op.            
  2515.               if (potTokIndirect->wLevel == 13)
  2516.                   wNewLev = 15;
  2517.             else                  
  2518.                   wNewLev = potTokIndirect->wLevel;
  2519.               if (*wLevel >= wNewLev) {
  2520.                 *wLevel = wNewLev;
  2521.                 return 0;
  2522.             } else {
  2523.                  oldLevel = *wLevel;
  2524.                 *wLevel = wNewLev;
  2525.  
  2526.                 ptNextValue = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
  2527.                 if (sRC) return sRC;                
  2528.                sRC = GetOp (pltLine, ptNextValue, wLevel, sFunc);
  2529.                 if (sRC) return sRC;
  2530.                 sRC = (*potTokIndirect->Fxn)(pltLine, ptCurrValue, ptNextValue);
  2531.                 DeleteToken (ptNextValue);
  2532.                 *wLevel = oldLevel;
  2533.             }
  2534.             break;
  2535.  
  2536.         default:
  2537.             if ((*pltLine)->ucType < TTYPE_EOL) {
  2538.                 ptInd = (PTOKEN) (*pltLine)->ptToken;
  2539.                 if (ptInd->ucNameLen != 0) {
  2540.                    SetToken (ptCurrValue, TTYPE_STR, 0, (DWORD)GetTokenStringL(ptInd));
  2541.                     *(PWORD)pltLine += ucTokLen;
  2542.                     break;
  2543.                 }
  2544.                sRC = ERR_EXPECTED_NUMBER;
  2545.             }
  2546.            sRC = ERR_EXPECTED_NUMBER;
  2547.     }    
  2548.     if (sRC) return sRC;
  2549.     oldLevel = (*wLevel)++;
  2550.     while (oldLevel < *wLevel) {
  2551.        *wLevel = oldLevel;
  2552.         ucTokLen = (*pltLine)->ucLen;
  2553.        
  2554.         if ((*pltLine)->ucType == TTYPE_EOL) {
  2555.            *wLevel = 0;
  2556.            return 0;
  2557.         } else {
  2558.               if (((*pltLine)->ucType == TTYPE_LOP) || 
  2559.                   ((*pltLine)->ucType == TTYPE_LUOP) ||
  2560.                   ((*pltLine)->ucType == TTYPE_ASSIGN_CMP)) {
  2561.  
  2562.                   potTokIndirect = (POPTOK)(*pltLine)->ptToken;
  2563.                   if (*wLevel >= potTokIndirect->wLevel) {
  2564.                     *wLevel = potTokIndirect->wLevel;
  2565.                     return 0;
  2566.                 } else {
  2567.                     *wLevel = potTokIndirect->wLevel;
  2568.                     *(PWORD)pltLine += ucTokLen;
  2569.  
  2570.                     ptNextValue = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
  2571.                     if (sRC) return sRC;
  2572.                    sRC = GetOp (pltLine, ptNextValue, wLevel, sFunc);
  2573.                     if (sRC) return sRC;
  2574.                     sRC = (*potTokIndirect->Fxn)(pltLine, ptCurrValue, ptNextValue);
  2575.                     DeleteToken (ptNextValue);
  2576.                 }
  2577.             } else if ((*pltLine)->ucType == TTYPE_OPAREN) {
  2578.                 sRC = ERR_BAD_FUNC_NAME;
  2579.                 break;
  2580.             } else if ((*pltLine)->ucType == TTYPE_BREAK) {
  2581.                 *(PWORD)pltLine += (*pltLine)->ucLen;
  2582.                *wLevel = 0;
  2583.             } else {
  2584.                *wLevel = 0;
  2585.               }   
  2586.         }        
  2587.     }               
  2588.     return sRC;
  2589. }
  2590. //------------------------------------------------------------
  2591. // Eval - Returns a token for an expression
  2592. //------------------------------------------------------------ 
  2593. INT Eval (LPLINETOKEN *pltLine, PTOKEN ptOut, INT sFunc) {
  2594.    UINT     wLevel = 1;
  2595.     return  GetOp (pltLine, ptOut, &wLevel, sFunc);
  2596. }    
  2597.  
  2598. //------------------------------------------------------------
  2599. // Eval2Num - Returns a number value for an expression
  2600. //------------------------------------------------------------ 
  2601. LONG Eval2Num (LPLINETOKEN *pltLine, INT sFunc, INT *sRC) {
  2602.    UINT         wLevel = 1;
  2603.    LONG        lResult;
  2604.    PTOKEN    ptTemp;
  2605.    
  2606.     ptTemp = AddToken (0, TTYPE_NUM, 0, 0, sRC);
  2607.     if (*sRC) return 0;
  2608.     *sRC = GetOp (pltLine, ptTemp, &wLevel, sFunc);
  2609.     lResult = GetTokenVal (ptTemp);
  2610.     DeleteToken (ptTemp);
  2611.     return lResult;
  2612. }    
  2613.  
  2614. //------------------------------------------------------------
  2615. // GetStatementType - Returns type of next token
  2616. //------------------------------------------------------------ 
  2617. BYTE GetStatementType (LPLINETOKEN pltNext) {
  2618.  
  2619.     if (pltNext->ucType == TTYPE_LINE)
  2620.           (PBYTE)pltNext += pltNext->ucLen;
  2621.     if (pltNext->ucType == TTYPE_CMT2EOL) {
  2622.        while (pltNext->ucType != TTYPE_EOL)
  2623.             (PBYTE)pltNext += pltNext->ucLen;
  2624.         (PBYTE)pltNext += pltNext->ucLen;
  2625.         return GetStatementType (pltNext);
  2626.     }    
  2627.     return pltNext->ucType;
  2628. }   
  2629.  
  2630. //------------------------------------------------------------
  2631. // ExecuteLine - Evaluates and calls the proper routine to
  2632. // execute a line in the file.
  2633. //------------------------------------------------------------ 
  2634. INT ExecuteLine (LPLINETOKEN *pltCurrent, INT sFunc) {
  2635.    BOOL  bContinue;
  2636.    INT    sRC = 0;
  2637.  
  2638.    if ((*pltCurrent)->ucType == TTYPE_EOF) {
  2639.       bRunning = FALSE;
  2640.       return RC_END_OF_PROGRAM;
  2641.    }
  2642.     if (sFunc & FUNC_EXECUTE) { 
  2643.         if (!bRunning) {
  2644.           bHold = TRUE;
  2645.             if ((*pltCurrent)->ucType == TTYPE_LINE) {
  2646.                wCurrentLine = ((LPLINESTARTTOK) *pltCurrent)->wLineNum;
  2647.             }
  2648.             PostMessage (hMain, MYMSG_REFRESH, 0, 0);
  2649.         }
  2650.        //Use Until loop to insure at least 1 yield per statement
  2651.         do {
  2652.            bContinue = MyYield();
  2653.         } while (bHold && bContinue);
  2654.  
  2655.         //If we recieved a WM_QUIT, report it
  2656.         if (!bContinue) 
  2657.             return ERR_UNEXP_PROGTERM;
  2658.     }
  2659.     //Execute a line
  2660.    sRC = Execute (pltCurrent, sFunc);
  2661.    return sRC;
  2662. }   
  2663.  
  2664. //------------------------------------------------------------
  2665. // Execute - Processes a series of tokens.
  2666. //------------------------------------------------------------ 
  2667. INT Execute (LPLINETOKEN *pltStart, INT sFunc) {
  2668.     LPLINETOKEN        pltCurr, pltNext;
  2669.     PSTATEMENTTOK    pstTokIndirect;
  2670.     INT                sRC = 0;
  2671.     PTOKEN            ptTemp;
  2672.  
  2673.     pltCurr = *pltStart;
  2674.  
  2675.     if (pltCurr->ucType == TTYPE_LINE) {
  2676.        wCurrentLine = ((LPLINESTARTTOK) pltCurr)->wLineNum;
  2677.           (PBYTE) pltCurr += pltCurr->ucLen;
  2678.     }
  2679.       (LPBYTE) pltNext = (LPBYTE) pltCurr + pltCurr->ucLen;
  2680.     switch (pltCurr->ucType) {
  2681.  
  2682.        case TTYPE_INTCMD:
  2683.        case TTYPE_STRCONST:
  2684.            sRC = LocalLaunch (&pltCurr, sFunc);
  2685.            *pltStart = pltCurr; 
  2686.            break;
  2687.  
  2688.        case TTYPE_VAR:
  2689.             if (sFunc == FUNC_EXECUTE) {
  2690.                if ((pltNext->ucType == TTYPE_ASSIGN) ||
  2691.                    (pltNext->ucType == TTYPE_ASSIGN_CMP))
  2692.                     sRC = LocalAssign (&pltCurr, sFunc);
  2693.                 else {
  2694.                    ptTemp = pltCurr->ptToken;
  2695.                    if (ptTemp->ucType == TTYPE_LABEL) {
  2696.                         ptTemp = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
  2697.                         if (sRC == 0) {
  2698.                               sRC = Eval (&pltCurr, ptTemp, sFunc);
  2699.                             DeleteToken (ptTemp);
  2700.                         }
  2701.                     } else
  2702.                         sRC = LocalLaunch (&pltCurr, sFunc);
  2703.                 }
  2704.             } else
  2705.                   SkipLine (&pltCurr);
  2706.            *pltStart = pltCurr; 
  2707.            break;
  2708.  
  2709.        case TTYPE_ENDBLK:
  2710.        case TTYPE_THENELSE:
  2711.        case TTYPE_LSTATEMENT:
  2712.               pstTokIndirect = (PSTATEMENTTOK)pltCurr->ptToken;
  2713.             sRC = (*pstTokIndirect->Fxn)(pltStart, sFunc);
  2714.            break;
  2715.  
  2716.         case TTYPE_LIBFUNC:
  2717.         case TTYPE_LOCALFUNC:
  2718.             if (sFunc == FUNC_EXECUTE) {
  2719.                 ptTemp = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
  2720.                 if (sRC == 0) {
  2721.                       sRC = Eval (&pltCurr, ptTemp, sFunc);
  2722.                     DeleteToken (ptTemp);
  2723.                     if (pltCurr->ucType == TTYPE_EOL)
  2724.                        (PBYTE)pltCurr += (WORD) pltCurr->ucLen;
  2725.                 }
  2726.             } else
  2727.                   SkipLine (&pltCurr);
  2728.            *pltStart = pltCurr; 
  2729.             break;
  2730.  
  2731.        case TTYPE_EOL:
  2732.            (PBYTE)pltCurr += (WORD) pltCurr->ucLen;
  2733.            *pltStart = pltCurr; 
  2734.           break;
  2735.  
  2736.        case TTYPE_EOF:
  2737.            *pltStart = pltCurr; 
  2738.           bRunning = FALSE;
  2739.           bHold = TRUE;
  2740.           sRC = RC_END_OF_PROGRAM;
  2741.             break;
  2742.            
  2743.         default:
  2744.             return ERR_SYNTAX;           
  2745.     }
  2746.     return sRC;
  2747. }
  2748.  
  2749. //------------------------------------------------------------
  2750. // LocalAssign - Assign a value to a token
  2751. //------------------------------------------------------------ 
  2752. INT LocalAssign (LPLINETOKEN *pltStart, INT sFunc){
  2753.     LPLINETOKEN    pltNext;
  2754.     INT            sRC = 0;
  2755.     PTOKEN        ptTemp, ptToken;
  2756.  
  2757.     if (sFunc & FUNC_SKIP) {
  2758.       SkipLine (pltStart);
  2759.         return 0;
  2760.     }
  2761.     pltNext = *pltStart;
  2762.     ptToken = (*pltStart)->ptToken;
  2763.    (PBYTE) pltNext += pltNext->ucLen;
  2764.       (PBYTE) pltNext += pltNext->ucLen;
  2765.       
  2766.     ptTemp = AddToken (0, TTYPE_NUM, 0, 0, &sRC);
  2767.     if (sRC == 0) {
  2768.           sRC = Eval (&pltNext, ptTemp, sFunc);
  2769.         if ((sRC == 0) && (sFunc & FUNC_EXECUTE)) {
  2770.             ptToken = (*pltStart)->ptToken;
  2771.             if (ptTemp->ucType == TTYPE_NUM) 
  2772.                 sRC = SetToken (ptToken, ptTemp->ucType, ptTemp->wData, 
  2773.                                 GetTokenVal (ptTemp));
  2774.             else                    
  2775.                 sRC = SetToken (ptToken, ptTemp->ucType, ptTemp->wData, 
  2776.                                 (DWORD)GetTokenStringL(ptTemp));
  2777.         }
  2778.         DeleteToken (ptTemp);
  2779.         if ((sRC == 0) && (pltNext->ucType != TTYPE_EOL))
  2780.             sRC = ERR_EXTRA_CHARS;
  2781.         (PBYTE)pltNext += (WORD) pltNext->ucLen;
  2782.     }    
  2783.     *pltStart = pltNext; 
  2784.     return sRC;
  2785. }        
  2786. //------------------------------------------------------------
  2787. // LocalLaunch - Launch a program
  2788. //------------------------------------------------------------ 
  2789. INT LocalLaunch (LPLINETOKEN *pltStart, INT sFunc){
  2790.    char    szProg[MAXLINELEN], chChar;
  2791.    char    *pszExt;
  2792.    char    *pszDefExt;
  2793.    INT    sRC, i, j;
  2794.    LPLINETOKEN  pltBegin;
  2795.    PTOKEN    ptName;
  2796.    OFSTRUCT    of;
  2797.    BOOL    bFound;
  2798.     UINT    wShowWin;
  2799.  
  2800.     if (sFunc & FUNC_SKIP) {
  2801.       SkipLine (pltStart);
  2802.         return 0;
  2803.     }
  2804.     if ((*pltStart)->ucType == TTYPE_LINE)
  2805.         *(PWORD)pltStart += (*pltStart)->ucLen;
  2806.  
  2807.    pltBegin = *pltStart;
  2808.     sRC = ResolveLine (pltStart, szProg, sizeof (szProg) - 5);
  2809.     if (sRC) return sRC;
  2810.     
  2811.     i = strcspn (szProg, " *+,/:;<>=|");
  2812.     chChar = szProg[i];
  2813.     szProg[i] = 0;
  2814.  
  2815.     strupr (szProg);
  2816.    bFound = FALSE;
  2817.    ptName = FindToken (szProg, i);
  2818.    if ((ptName != 0) && (ptName->ucType == TTYPE_INTCMD)) {
  2819.        strcpy (szProg, getenv("COMSPEC"));
  2820.        strcat (szProg, " /C ");
  2821.        i = strlen (szProg);
  2822.         sRC = ResolveLine (&pltBegin, szProg+i, sizeof (szProg) - i);
  2823.         wShowWin = SW_SHOWMINIMIZED;
  2824.         bFound = TRUE;
  2825.     } else {    
  2826.         pszExt = strrchr (szProg, '.');
  2827.         if ((pszExt == 0) || (pszExt < strrchr(szProg, '\\'))) {
  2828.            //Make room on cmdline for ext
  2829.             for (j = strlen (&szProg[i+1])+3; j > 0; j--) 
  2830.                 szProg[i+j+4] = szProg[i+j];
  2831.        
  2832.             szProg[i] = '.';
  2833.             szProg[i+4] = 0;
  2834.             pszDefExt = szProgExt;
  2835.             bFound = FALSE;
  2836.             while (*pszDefExt != 0) {
  2837.                for (j = 0; j < 3; j++)
  2838.                     szProg[i+j+1] = *pszDefExt++;
  2839.             
  2840.                 if (OpenFile (szProg, &of, OF_EXIST) != HFILE_ERROR) {
  2841.                     bFound = TRUE;
  2842.                     break;
  2843.                 }    
  2844.                 while ((*pszDefExt <= ' ') && (*pszDefExt != 0))
  2845.                     pszDefExt++;
  2846.             }
  2847.             szProg[i+4] = chChar;
  2848.         } else {
  2849.             szProg[i] = chChar;
  2850.             bFound = TRUE;
  2851.         }    
  2852.         wShowWin = SW_SHOWNORMAL;
  2853.     }    
  2854.     if (bFound) {
  2855.         sRC = WinExec (szProg, wShowWin);
  2856.         if (sRC < 32)
  2857.            sRC = ERR_LAUNCH_ERR - sRC;
  2858.         else
  2859.            sRC = 0;
  2860.     } else
  2861.        sRC = ERR_FOPEN_ERR - of.nErrCode;
  2862.     *(PWORD)pltStart += (*pltStart)->ucLen;
  2863.    return sRC;
  2864.  
  2865. //    sRC = WinExec (szProg, SW_SHOWMINIMIZED);
  2866. }
  2867.  
  2868. //------------------------------------------------------------
  2869. // While - While loop statement
  2870. //------------------------------------------------------------ 
  2871. INT LocalWHILE (LPLINETOKEN *pltStart, INT sFunc){
  2872.     LPLINETOKEN    pltNext, pltSave;
  2873.     INT            sRC = 0;
  2874.  
  2875.     pltNext = *pltStart;
  2876.     if (pltNext->ucType == TTYPE_LINE)
  2877.        (PBYTE) pltNext += pltNext->ucLen;
  2878.    (PBYTE) pltNext += pltNext->ucLen;
  2879.     
  2880.     if (!Eval2Num (&pltNext, sFunc, &sRC))
  2881.         sFunc = FUNC_SKIP;
  2882.     if (sRC) return sRC;
  2883.  
  2884.     pltSave = pltNext;    
  2885.     if (pltNext->ucType == TTYPE_EOL) {
  2886.        (PBYTE) pltNext += pltNext->ucLen;
  2887.         sRC = ExecuteLine (&pltNext, sFunc);
  2888.     } else {
  2889.         sRC = Execute (&pltNext, sFunc);
  2890.         if (pltNext->ucType == TTYPE_EOL)
  2891.            (PBYTE) pltNext += pltNext->ucLen;
  2892.     }
  2893.     if (sRC == RC_END_OF_LOOP) {
  2894.        sRC = 0;
  2895.        pltNext = pltSave;
  2896.         if (pltNext->ucType == TTYPE_EOL) {
  2897.            (PBYTE) pltNext += pltNext->ucLen;
  2898.             sRC = ExecuteLine (&pltNext, FUNC_SKIP);
  2899.         } else {
  2900.             sRC = Execute (&pltNext, FUNC_SKIP);
  2901.             if (pltNext->ucType == TTYPE_EOL)
  2902.                (PBYTE) pltNext += pltNext->ucLen;
  2903.         }
  2904.         *pltStart = pltNext;
  2905.     }    
  2906.     if (sFunc & FUNC_SKIP)
  2907.         *pltStart = pltNext;
  2908.  
  2909.     return sRC;
  2910. }
  2911.  
  2912. //------------------------------------------------------------
  2913. // IF - If statement
  2914. //------------------------------------------------------------ 
  2915. INT LocalIF (LPLINETOKEN *pltStart, INT sFunc) {
  2916.     LPLINETOKEN    pltNext;
  2917.     LONG            lResult;
  2918.     INT            sRC = 0;
  2919.  
  2920.     pltNext = *pltStart;
  2921.     if (pltNext->ucType == TTYPE_LINE)
  2922.        (PBYTE) pltNext += pltNext->ucLen;
  2923.    (PBYTE) pltNext += pltNext->ucLen;
  2924.     
  2925.     lResult = Eval2Num (&pltNext, sFunc, &sRC);
  2926.     if (sRC) return sRC;
  2927.  
  2928.     if (pltNext->ucType != TTYPE_EOL) {  // If <then> clause on same line as IF
  2929.        if (lResult) {
  2930.           if (sFunc == FUNC_EXECUTE) {
  2931.               sRC = Execute (&pltNext, sFunc);
  2932.               if (pltNext->ucType == TTYPE_EOL) 
  2933.                    (PBYTE) pltNext += pltNext->ucLen;
  2934.           }
  2935.           if (GetStatementType (pltNext) == TTYPE_THENELSE)
  2936.                 sRC = ExecuteLine (&pltNext, FUNC_SKIP);
  2937.         } else 
  2938.           sRC = Execute (&pltNext, FUNC_SKIP);
  2939.  
  2940.     } else { // If <then> clause on next line
  2941.         (PBYTE) pltNext += pltNext->ucLen;
  2942.        if (lResult) {
  2943.             sRC = ExecuteLine (&pltNext, sFunc);
  2944.           if (GetStatementType (pltNext) == TTYPE_THENELSE) {
  2945.                 sRC = ExecuteLine (&pltNext, FUNC_SKIP);
  2946.             }    
  2947.         } else 
  2948.             sRC = ExecuteLine (&pltNext, FUNC_SKIP);
  2949.     }
  2950.     *pltStart = pltNext;
  2951.     return sRC;
  2952. }
  2953.  
  2954. //------------------------------------------------------------
  2955. // Then/Else Statements
  2956. //------------------------------------------------------------ 
  2957. INT LocalThenElse (LPLINETOKEN *pltStart, INT sFunc) {
  2958.     LPLINETOKEN    pltNext;
  2959.     INT         sRC = 0;
  2960.  
  2961.     pltNext = *pltStart;
  2962.     if (pltNext->ucType == TTYPE_LINE)
  2963.        (PBYTE) pltNext += pltNext->ucLen;
  2964.    (PBYTE) pltNext += pltNext->ucLen;
  2965.     
  2966.     if (pltNext->ucType != TTYPE_EOL)      // More on same line
  2967.        sRC = Execute (&pltNext, sFunc);
  2968.     else {                                 // Execute Next line
  2969.           (PBYTE) pltNext += pltNext->ucLen;
  2970.         sRC = ExecuteLine (&pltNext, sFunc);
  2971.    }
  2972.     *pltStart = pltNext;
  2973.     return sRC;
  2974. }
  2975.  
  2976. //------------------------------------------------------------
  2977. // LocalDO - DO statement
  2978. //------------------------------------------------------------ 
  2979. INT LocalDO (LPLINETOKEN *pltStart, INT sFunc) {
  2980.     LPLINETOKEN    pltNext;
  2981.     INT            sRC = 0;
  2982.  
  2983.     pltNext = *pltStart;
  2984.     if (pltNext->ucType == TTYPE_LINE)
  2985.        (PBYTE) pltNext += pltNext->ucLen;
  2986.    (PBYTE) pltNext += pltNext->ucLen;
  2987.  
  2988.     if (pltNext->ucType != TTYPE_EOL) 
  2989.         return  ERR_EXTRA_CHARS;
  2990.  
  2991.     (PBYTE) pltNext += pltNext->ucLen;
  2992.  
  2993.     while (sRC == 0) 
  2994.         sRC = ExecuteLine (&pltNext, sFunc);
  2995.  
  2996.     *pltStart = pltNext;
  2997.     if (sRC != RC_END_OF_BLOCK) 
  2998.         return sRC;
  2999.     return 0;
  3000. }
  3001.  
  3002. //------------------------------------------------------------
  3003. // LocalEND - END statement ends a block
  3004. //------------------------------------------------------------ 
  3005. INT LocalEND (LPLINETOKEN *pltStart, INT sFunc) {
  3006.  
  3007.     if ((*pltStart)->ucType == TTYPE_LINE)
  3008.         *(PWORD)pltStart += (*pltStart)->ucLen;
  3009.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3010.  
  3011.     if ((*pltStart)->ucType != TTYPE_EOL) 
  3012.         return  ERR_EXTRA_CHARS;
  3013.  
  3014.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3015.     return RC_END_OF_BLOCK;
  3016. }
  3017.  
  3018. //------------------------------------------------------------
  3019. // LocalRETURN - RETURN statement returns from a sub or
  3020. // function.
  3021. //------------------------------------------------------------ 
  3022. INT LocalRETURN (LPLINETOKEN *pltStart, INT sFunc) {
  3023.    INT        sRC = 0;
  3024.    PTOKEN    ptRetVal;
  3025.  
  3026.     if (sFunc & FUNC_SKIP) {
  3027.       SkipLine (pltStart);
  3028.         return 0;
  3029.     }
  3030.     if ((*pltStart)->ucType == TTYPE_LINE)
  3031.         *(PWORD)pltStart += (*pltStart)->ucLen;
  3032.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3033.  
  3034.     
  3035.     ptRetVal = FindTokenByType (TTYPE_RETVAL);
  3036.     ptRetVal->ucType = TTYPE_NUM;
  3037.  
  3038.     if ((*pltStart)->ucType == TTYPE_EOL) 
  3039.         return RC_END_OF_SUB;
  3040.  
  3041.     if (ptRetVal != 0) {
  3042.         sRC = Eval (pltStart, ptRetVal, sFunc);
  3043.         if (sRC) 
  3044.             return sRC;
  3045.     }
  3046.     if ((*pltStart)->ucType == TTYPE_EOL) 
  3047.         *(PWORD)pltStart += (*pltStart)->ucLen;
  3048.     return RC_END_OF_SUB;
  3049. }
  3050. //------------------------------------------------------------
  3051. // LocalLEAVE - LEAVE statement exits from a loop
  3052. // 
  3053. //------------------------------------------------------------ 
  3054. INT LocalLEAVE (LPLINETOKEN *pltStart, INT sFunc) {
  3055.  
  3056.     if (sFunc & FUNC_SKIP) {
  3057.       SkipLine (pltStart);
  3058.         return 0;
  3059.     }
  3060.     if ((*pltStart)->ucType == TTYPE_LINE)
  3061.         *(PWORD)pltStart += (*pltStart)->ucLen;
  3062.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3063.  
  3064.     if ((*pltStart)->ucType != TTYPE_EOL) 
  3065.         return ERR_EXTRA_CHARS;
  3066.     else
  3067.         return RC_END_OF_LOOP;
  3068. }
  3069.  
  3070. //------------------------------------------------------------
  3071. // LocalCMT2EOL- Comment statment, line ignored
  3072. // function.
  3073. //------------------------------------------------------------ 
  3074. INT LocalCMT2EOL (LPLINETOKEN *pltStart, INT sFunc) {
  3075.     SkipLine (pltStart);
  3076.     return 0;
  3077. }
  3078.  
  3079. //------------------------------------------------------------
  3080. // LocalEXIT - EXIT statement terminates program
  3081. //------------------------------------------------------------ 
  3082. INT LocalEXIT (LPLINETOKEN *pltStart, INT sFunc) {
  3083.    INT    sRC = 0;
  3084.  
  3085.     if (sFunc & FUNC_SKIP) {
  3086.       SkipLine (pltStart);
  3087.         return 0;
  3088.     }
  3089.     if ((*pltStart)->ucType == TTYPE_LINE)
  3090.         *(PWORD)pltStart += (*pltStart)->ucLen;
  3091.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3092.  
  3093.     if ((*pltStart)->ucType == TTYPE_EOL) 
  3094.         return RC_END_OF_PROGRAM;
  3095.     
  3096.     sFinalRC = (INT) Eval2Num (pltStart, sFunc, &sRC);
  3097.     if (sRC) 
  3098.         return sRC;
  3099.     else
  3100.         return RC_END_OF_PROGRAM;
  3101. }
  3102.  
  3103. //------------------------------------------------------------
  3104. // LocalSAY - SAY statement
  3105. //------------------------------------------------------------ 
  3106. INT LocalSAY (LPLINETOKEN *pltStart, INT sFunc) {
  3107.    char    szOutput[MAXLINELEN];
  3108.    INT    sRC;
  3109.  
  3110.     if (sFunc & FUNC_SKIP) {
  3111.       SkipLine (pltStart);
  3112.         return 0;
  3113.     }
  3114.     if ((*pltStart)->ucType == TTYPE_LINE)
  3115.         *(PWORD)pltStart += (*pltStart)->ucLen;
  3116.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3117.  
  3118.     sRC = ResolveLine (pltStart, szOutput, sizeof (szOutput));
  3119.     if (sRC) return sRC;
  3120.     WriteOutput (hMain, szOutput);    
  3121.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3122.     return sRC;
  3123. }
  3124. //------------------------------------------------------------
  3125. // LocalChDir - ChDir changes the current directory
  3126. //------------------------------------------------------------ 
  3127. INT LocalChDir (LPLINETOKEN *pltStart, INT sFunc) {
  3128.    char    szOutput[MAXLINELEN];
  3129.    INT    sRC;
  3130.  
  3131.     if (sFunc & FUNC_SKIP) {
  3132.       SkipLine (pltStart);
  3133.         return 0;
  3134.     }
  3135.     if ((*pltStart)->ucType == TTYPE_LINE)
  3136.         *(PWORD)pltStart += (*pltStart)->ucLen;
  3137.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3138.  
  3139.     if ((*pltStart)->ucType != TTYPE_EOL) {
  3140.         sRC = ResolveLine (pltStart, szOutput, sizeof (szOutput));
  3141.         if (sRC) return sRC;
  3142.         if (strlen (szOutput) < 128) 
  3143.             sRC = chdir (_fullpath(&szOutput[128], szOutput, sizeof (szOutput)-128));
  3144.         else                        
  3145.             sRC = chdir(szOutput);
  3146.         if (sRC != 0)
  3147.            sRC = ERR_PATH_NOT_FOUND;
  3148.     } else {
  3149.        getcwd (szOutput, sizeof (szOutput));
  3150.         WriteOutput (hMain, szOutput);
  3151.         sRC = 0;       
  3152.     }  
  3153.     *(PWORD)pltStart += (*pltStart)->ucLen;
  3154.     return sRC;
  3155. }
  3156. //------------------------------------------------------------
  3157. // Operators 
  3158. //------------------------------------------------------------ 
  3159. //------------------------------------------------------------
  3160. // LocalOpAdd - Adds two numbers
  3161. //------------------------------------------------------------ 
  3162. INT LocalOpAdd (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3163.    LONG    lTemp, lSrc, lDest;
  3164.    INT    sRC = 0;
  3165.  
  3166.     if ((ptDest->ucType == TTYPE_STR) && (ptSrc->ucType != TTYPE_NUM)) {
  3167.         sRC = AppendString (ptDest, GetTokenString (ptSrc));
  3168.     } else {
  3169.         lSrc = GetTokenVal (ptSrc);
  3170.         lDest = GetTokenVal (ptDest);
  3171.         lTemp = lSrc + lDest;
  3172.         if (!((lDest ^ lSrc)  & 0x80000000) &&
  3173.              ((lDest ^ lTemp) & 0x80000000)) 
  3174.             sRC = ERR_OVERFLOW;
  3175.         else
  3176.             sRC = SetToken (ptDest, TTYPE_NUM, 0, lTemp);
  3177.     }    
  3178.       return sRC;
  3179. }      
  3180. //------------------------------------------------------------
  3181. // LocalOpSub - Subtracts two numbers
  3182. //------------------------------------------------------------ 
  3183. INT LocalOpSub (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3184.    LONG    lTemp, lSrc, lDest;
  3185.    INT    sRC = 0;
  3186.  
  3187.     lSrc = GetTokenVal (ptSrc);
  3188.     lDest = GetTokenVal (ptDest);
  3189.     lTemp = lDest - lSrc;
  3190.     if (((lDest ^ lSrc) & 0x80000000) &&
  3191.         ((lDest ^ lTemp) & 0x80000000)) 
  3192.         sRC = ERR_OVERFLOW;
  3193.     else
  3194.         sRC = SetToken (ptDest, TTYPE_NUM, 0, lTemp);
  3195.       return sRC;
  3196. }
  3197. //------------------------------------------------------------
  3198. // LocalOpMul - Multiplies two numbers
  3199. //------------------------------------------------------------ 
  3200. INT LocalOpMul (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3201.    LONG    lTemp, lSrc, lDest;
  3202.    INT    sRC = 0;
  3203.  
  3204.     lSrc = GetTokenVal (ptSrc);
  3205.     lDest = GetTokenVal (ptDest);
  3206.     lTemp = lDest * lSrc;
  3207.     if (((lDest ^ lSrc) & 0x80000000) && (lTemp >= 0) ||
  3208.         !((lDest ^ lSrc) & 0x80000000) && (lTemp < 0)) 
  3209.         sRC = ERR_OVERFLOW;
  3210.     else
  3211.         sRC = SetToken (ptDest, TTYPE_NUM, 0, lTemp);
  3212.       return sRC;
  3213. }      
  3214. //------------------------------------------------------------
  3215. // LocalOpDiv - Divides two numbers
  3216. //------------------------------------------------------------ 
  3217. INT LocalOpDiv (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3218.    LONG lTemp;
  3219.  
  3220.    lTemp = GetTokenVal (ptSrc);
  3221.     if (lTemp == 0) return ERR_DIVIDE_BY_ZERO;
  3222.     return SetToken (ptDest, TTYPE_NUM, 0, GetTokenVal(ptDest) / lTemp); 
  3223. }      
  3224. //------------------------------------------------------------
  3225. // LocalOpLThan - Less than comparision
  3226. //------------------------------------------------------------ 
  3227. INT LocalOpLThan (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3228.     if (ptDest->dwData < ptSrc->dwData)
  3229.         ptDest->dwData = MYTRUE;
  3230.     else
  3231.         ptDest->dwData = MYFALSE;
  3232.     ptDest->ucType = TTYPE_NUM;
  3233.       return 0;
  3234. }      
  3235. //------------------------------------------------------------
  3236. // LocalOpLEThan - Less or equal comparision
  3237. //------------------------------------------------------------ 
  3238. INT LocalOpLEThan (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3239.     if (ptDest->dwData <= ptSrc->dwData)
  3240.         ptDest->dwData = MYTRUE;
  3241.     else
  3242.         ptDest->dwData = MYFALSE;
  3243.     ptDest->ucType = TTYPE_NUM;
  3244.       return 0;
  3245. }      
  3246. //------------------------------------------------------------
  3247. // LocalOpGThan - Greater than comparision
  3248. //------------------------------------------------------------ 
  3249. INT LocalOpGThan (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3250.     if (ptDest->dwData > ptSrc->dwData)
  3251.         ptDest->dwData = MYTRUE;
  3252.     else
  3253.         ptDest->dwData = MYFALSE;
  3254.     ptDest->ucType = TTYPE_NUM;
  3255.       return 0;
  3256. }      
  3257. //------------------------------------------------------------
  3258. // LocalOpGEThan - Greater or equal comparision
  3259. //------------------------------------------------------------ 
  3260. INT LocalOpGEThan (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3261.     if (ptDest->dwData >= ptSrc->dwData)
  3262.         ptDest->dwData = MYTRUE;
  3263.     else
  3264.         ptDest->dwData = MYFALSE;
  3265.     ptDest->ucType = TTYPE_NUM;
  3266.       return 0;
  3267. }      
  3268. //------------------------------------------------------------
  3269. // LocalOpNotEqual - Not equal comparison
  3270. //------------------------------------------------------------ 
  3271. INT LocalOpNotEqual (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3272.    INT    sRC;
  3273.    sRC = LocalOpCmp (pltLine, ptDest, ptSrc);
  3274.    if (sRC == 0)
  3275.         if (ptDest->dwData == MYFALSE)
  3276.             ptDest->dwData = MYTRUE;
  3277.         else
  3278.             ptDest->dwData = MYFALSE;
  3279.       return sRC;
  3280. }      
  3281. //------------------------------------------------------------
  3282. // LocalOpCmp - Equal comparison
  3283. //------------------------------------------------------------ 
  3284. INT LocalOpCmp (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3285.     if (ptDest->ucType == ptSrc->ucType) {
  3286.         if (ptDest->ucType == TTYPE_NUM) {
  3287.            if (GetTokenVal (ptDest) == GetTokenVal(ptSrc))
  3288.                 ptDest->dwData = MYTRUE;
  3289.             else
  3290.                 ptDest->dwData = MYFALSE;
  3291.         } else if (ptDest->ucType == TTYPE_STR) {
  3292.          if (lstrcmp (GetTokenStringL(ptDest),GetTokenStringL(ptSrc)) == 0)
  3293.                 ptDest->dwData = MYTRUE;
  3294.             else
  3295.                 ptDest->dwData = MYFALSE;
  3296.         } else
  3297.             ptDest->dwData = MYFALSE;
  3298.     } else
  3299.         ptDest->dwData = MYFALSE;
  3300.     ptDest->ucType = TTYPE_NUM;
  3301.    return 0;
  3302. }      
  3303. //------------------------------------------------------------
  3304. // LocalOpAND - Logical AND
  3305. //------------------------------------------------------------ 
  3306. INT LocalOpAND (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3307.  
  3308.    if (GetTokenVal (ptSrc) && GetTokenVal (ptDest))
  3309.         SetToken (ptDest, TTYPE_NUM, 0, MYTRUE);
  3310.     else
  3311.         SetToken (ptDest, TTYPE_NUM, 0, MYFALSE);
  3312.       return 0;
  3313. }      
  3314. //------------------------------------------------------------
  3315. // LocalOpANDBits - Bitwise AND
  3316. //------------------------------------------------------------ 
  3317. INT LocalOpANDBits (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3318.     return SetToken (ptDest, TTYPE_NUM, 0, GetTokenVal (ptSrc) & 
  3319.                                            GetTokenVal (ptDest));
  3320. }      
  3321. //------------------------------------------------------------
  3322. // LocalOpOR - Logical OR
  3323. //------------------------------------------------------------ 
  3324. INT LocalOpOR (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3325.  
  3326.    if (GetTokenVal (ptSrc) || GetTokenVal (ptDest))
  3327.         SetToken (ptDest, TTYPE_NUM, 0, MYTRUE);
  3328.     else
  3329.         SetToken (ptDest, TTYPE_NUM, 0, MYFALSE);
  3330.       return 0;
  3331. }      
  3332. //------------------------------------------------------------
  3333. // LocalOpORBits - Bitwise OR
  3334. //------------------------------------------------------------ 
  3335. INT LocalOpORBits (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3336.     return SetToken (ptDest, TTYPE_NUM, 0, GetTokenVal (ptSrc) | 
  3337.                                            GetTokenVal (ptDest));
  3338. }      
  3339. //------------------------------------------------------------
  3340. // LocalOpXOR - Logical XOR
  3341. //------------------------------------------------------------ 
  3342. INT LocalOpXOR (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3343.  
  3344.    if ( (GetTokenVal (ptSrc) && GetTokenVal (ptDest)) ||
  3345.        !(GetTokenVal (ptSrc) && GetTokenVal (ptDest)))
  3346.         SetToken (ptDest, TTYPE_NUM, 0, MYTRUE);
  3347.     else
  3348.         SetToken (ptDest, TTYPE_NUM, 0, MYFALSE);
  3349.       return 0;
  3350. }      
  3351. //------------------------------------------------------------
  3352. // LocalOpXORBits - Bitwise XOR
  3353. //------------------------------------------------------------ 
  3354. INT LocalOpXORBits (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3355.     return SetToken (ptDest, TTYPE_NUM, 0, GetTokenVal (ptSrc) ^ 
  3356.                                            GetTokenVal (ptDest));
  3357. }      
  3358. //------------------------------------------------------------
  3359. // LocalOpNOT - Logical NOT
  3360. //------------------------------------------------------------ 
  3361. INT LocalOpNOT (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3362.  
  3363.    if (GetTokenVal (ptSrc))
  3364.         SetToken (ptDest, TTYPE_NUM, 0, MYFALSE);
  3365.     else
  3366.         SetToken (ptDest, TTYPE_NUM, 0, MYTRUE);
  3367.       return 0;
  3368. }      
  3369. //------------------------------------------------------------
  3370. // LocalOpNOTBits - Bitwise NOT
  3371. //------------------------------------------------------------ 
  3372. INT LocalOpNOTBits (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3373.     return SetToken (ptDest, TTYPE_NUM, 0, ~GetTokenVal (ptSrc));
  3374. }      
  3375. //------------------------------------------------------------
  3376. // LocalOpOComma - Pauses current evaluation
  3377. //------------------------------------------------------------ 
  3378. INT LocalComma (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3379.       return 0;
  3380. }      
  3381. //------------------------------------------------------------
  3382. // LocalOpOParen - Processes open paren character
  3383. //------------------------------------------------------------ 
  3384. INT LocalOpOPren (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3385.    INT    sRC;
  3386.  
  3387.     sRC = Eval (pltLine, ptDest, FUNC_EXECUTE);
  3388.     if (sRC) return sRC;
  3389.     if ((*pltLine)->ucType != TTYPE_CPAREN) 
  3390.       return ERR_NO_CLOSE_PAREN;
  3391.  
  3392.     sRC = (*pltLine)->ucLen;
  3393.     *(PWORD)pltLine += sRC;
  3394.     sRC = 0;
  3395.  
  3396.     return sRC;            
  3397. }
  3398. INT LocalOpCPren (LPLINETOKEN *pltLine, PTOKEN ptDest, PTOKEN ptSrc) {
  3399.       return ERR_NO_OPEN_PAREN;
  3400. }      
  3401. //------------------------------------------------------------
  3402. // Predefined functions
  3403. //------------------------------------------------------------ 
  3404. //------------------------------------------------------------
  3405. // LocalLENGTH - Predefined func that returns the length of a string
  3406. //------------------------------------------------------------ 
  3407. INT LocalLENGTH (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3408.    PTOKEN    ptArg;
  3409.   
  3410.    ptArg = (PTOKEN) ptDest->dwData;   
  3411.    ptDest->dwData = 0;
  3412.    if (ptDest->wData != 0) 
  3413.       return SetToken (ptDest, TTYPE_NUM, 0, 
  3414.                        strlen (GetTokenString (ptArg-1)));
  3415.    else
  3416.       return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)szNull);
  3417. }      
  3418. //------------------------------------------------------------
  3419. // LocalUPPER - Predefined func that converts a string to
  3420. // upper case.
  3421. //------------------------------------------------------------ 
  3422. INT LocalUPPER (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3423.    PTOKEN    ptArg;
  3424.    
  3425.    ptArg = (PTOKEN) ptDest->dwData;   
  3426.    ptDest->dwData = 0;
  3427.    if (ptDest->wData != 0) 
  3428.       return SetToken (ptDest, TTYPE_STR, 0, 
  3429.                    (DWORD)(LPSTR)strupr(GetTokenString(ptArg-1)));
  3430.    else
  3431.       return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)szNull);
  3432. }      
  3433. //------------------------------------------------------------
  3434. // LocalSUBSTR - Predefined func that returns a portion of a 
  3435. // string.
  3436. //------------------------------------------------------------ 
  3437. INT LocalSUBSTR (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3438.    INT        sRC = 0;
  3439.    UINT        wStart = 0, wLen = 0xffff, wStrLen;
  3440.    char        chChar;
  3441.    char        *pszSrc;
  3442.    PTOKEN    ptArg;
  3443.    
  3444.    ptArg = (PTOKEN) ptDest->dwData;   
  3445.     if (ptDest->wData > 2)
  3446.        wLen = (WORD) GetTokenVal (ptArg-3);
  3447.  
  3448.     if (ptDest->wData > 1)
  3449.        wStart = (WORD) GetTokenVal (ptArg-2);
  3450.     
  3451.     pszSrc = (char *)(ptArg-1)->dwData;
  3452.     wStrLen = strlen (pszSrc);
  3453.     if (wStart > wStrLen)
  3454.        ptDest->dwData = 0;
  3455.     else {
  3456.        pszSrc += wStart;
  3457.         wStrLen = strlen (pszSrc);
  3458.         if (wLen < wStrLen) {
  3459.            chChar = *(pszSrc+wLen);
  3460.            *(pszSrc+wLen) = 0;
  3461.         }
  3462.        ptDest->ucType = TTYPE_NUM;
  3463.         sRC = SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)pszSrc);
  3464.         if (wLen < wStrLen) 
  3465.            *(pszSrc+wLen) = chChar;
  3466.     }
  3467.    ptDest->ucType = TTYPE_STR;
  3468.    ptDest->wData = 0;
  3469.       return sRC;
  3470. }      
  3471. //------------------------------------------------------------
  3472. // LocalARG - Predefined func that returns an a calling arg.
  3473. //------------------------------------------------------------ 
  3474. INT LocalARG (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3475.    INT        sRC;
  3476.    PTOKEN    ptArg, ptRetVal;
  3477.  
  3478.    ptDest->ucType = TTYPE_NUM;
  3479.     ptRetVal = FindTokenByType (TTYPE_RETVAL);
  3480.     if (ptRetVal == 0)
  3481.        return ERR_NOARGS;
  3482.     if (ptDest->wData == 1) {
  3483.         sRC = SetToken (ptDest, TTYPE_NUM, 0, (DWORD)ptRetVal->wData-1);
  3484.     } else {
  3485.        ptArg = (PTOKEN) ptDest->dwData;
  3486.         if (ptRetVal->wData <= (UINT) GetTokenVal (ptArg-1)) {
  3487.             sRC = SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)szNull);
  3488.         } else {           
  3489.             ptRetVal = (PTOKEN)ptRetVal->dwData;
  3490.             ptRetVal -= GetTokenVal (ptArg-1);
  3491.             sRC = SetToken (ptDest, ptRetVal->ucType, ptRetVal->wData, ptRetVal->dwData);
  3492.         }
  3493.     }               
  3494.       return sRC;
  3495. }      
  3496. //------------------------------------------------------------
  3497. // LocalWAIT - Predefined func that stops execution for a 
  3498. // number of milliseconds.
  3499. // Arg 1 - Number of milliseconds to wait
  3500. //------------------------------------------------------------ 
  3501. INT LocalWAIT (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3502.     PTOKEN    ptArg;
  3503.     UINT        wDelay;
  3504.  
  3505.    if (bRunning == FALSE)
  3506.       return 0;
  3507.  
  3508.     ptArg = (PTOKEN) ptDest->dwData;
  3509.     if (ptDest->wData < 2) 
  3510.         return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
  3511.     
  3512.     wDelay = (UINT) GetTokenVal (ptArg-1);
  3513.     if (wDelay == 0)
  3514.         return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
  3515.     if (GetTokenVal (ptArg-1) > 0xffff)
  3516.        wDelay = 0xffff;
  3517.  
  3518.     hWaitTimer = SetTimer (hMain, WAITTIMER_ID, wDelay, 0);
  3519.     if (hWaitTimer == 0)
  3520.         return ERR_NO_TIMERS;
  3521.     bHold = TRUE;
  3522.     return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYTRUE);
  3523. }      
  3524. //------------------------------------------------------------
  3525. // Predefined functions useful in Windows
  3526. //------------------------------------------------------------ 
  3527. INT MyGetWindowText (HWND hWnd, LPSTR lpszOut, UINT wLen) {
  3528.    return (INT) SendMessage (hWnd, WM_GETTEXT, wLen, (DWORD) lpszOut);
  3529. }   
  3530. //------------------------------------------------------------
  3531. // WinActivate - Predefined func that sets the input focus to
  3532. // a window
  3533. // Arg 1 - Window title text
  3534. //------------------------------------------------------------ 
  3535. INT WinActivate (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3536.     char        szWinText[MAXLINELEN];
  3537.     PTOKEN    ptArg;
  3538.     HWND        hWndTarg, hWndT2;
  3539.     
  3540.     ptArg = (PTOKEN) ptDest->dwData;   
  3541.     hWndTarg = FindWindow (0, GetTokenString(ptArg-1));
  3542.     if (hWndTarg != 0) {  
  3543.         hWndT2 = SetActiveWindow (hWndTarg);
  3544.         MyGetWindowText (hWndT2, szWinText, sizeof szWinText);
  3545.         return SetToken (ptDest, TTYPE_STR, 0,(DWORD)(LPSTR)szWinText);
  3546.     } else    
  3547.         return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
  3548. }      
  3549. //------------------------------------------------------------
  3550. // WinSendKeys - Predefined func that sends keys to a window
  3551. // Arg 1 - Key string
  3552. //------------------------------------------------------------ 
  3553. INT WinSendKeys (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3554.     PTOKEN    ptArg;
  3555.     char        *pszKeyString;
  3556.     INT        sRC;
  3557.     
  3558.     ptArg = (PTOKEN) ptDest->dwData;   
  3559.     if (ptDest->wData > 1) {
  3560.         pszKeyString = GetTokenString (ptArg-1);
  3561.         sRC = StuffKeyString (&pszKeyString);
  3562.         if (sRC) return sRC;
  3563.         return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYTRUE);
  3564.     }
  3565.     return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
  3566. }      
  3567. //------------------------------------------------------------
  3568. // WinGetActWin - Predefined func that returns the text of
  3569. // the active window.
  3570. // No Args
  3571. //------------------------------------------------------------ 
  3572. INT WinGetActWin (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3573.     char        szWinText[MAXLINELEN];
  3574.     
  3575.     MyGetWindowText (GetActiveWindow(), szWinText, sizeof szWinText);
  3576.     return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR) szWinText);
  3577. }      
  3578. //------------------------------------------------------------
  3579. // WinGetNextWin - Predefined func that returns the text of
  3580. // the next window in the window list.
  3581. // Arg 1 - Window title text
  3582. //------------------------------------------------------------ 
  3583. INT WinGetNextWin (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3584.     char        szWinText[MAXLINELEN];
  3585.     PTOKEN    ptArg;
  3586.     HWND        hWndTarg;
  3587.     
  3588.     ptArg = (PTOKEN) ptDest->dwData;   
  3589.     hWndTarg = FindWindow (0, GetTokenString(ptArg-1));
  3590.     hWndTarg = GetNextWindow(hWndTarg, GW_HWNDNEXT);
  3591.     if (hWndTarg == 0)
  3592.         return SetToken (ptDest, TTYPE_STR, 0, MYFALSE);
  3593.     MyGetWindowText (hWndTarg, szWinText, sizeof szWinText);
  3594.     return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR) szWinText);
  3595. }      
  3596.  
  3597. //------------------------------------------------------------
  3598. // WinGetWinEXE - Predefined func that returns the name of the
  3599. // EXE that created a window
  3600. // Arg 1 - Window title text
  3601. //------------------------------------------------------------ 
  3602. INT WinGetWinEXE (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3603.     char        szWinText[MAXLINELEN];
  3604.     PTOKEN    ptArg;
  3605.     HWND        hWndTarg;
  3606.     
  3607.     ptArg = (PTOKEN) ptDest->dwData;
  3608.     if (ptDest->wData > 1) {
  3609.         hWndTarg = FindWindow (0, GetTokenString(ptArg-1));
  3610.         if (hWndTarg != 0) {  
  3611.             GetModuleFileName (GetWindowWord (hWndTarg, GWW_HINSTANCE),
  3612.                                szWinText, sizeof (szWinText));
  3613.             return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR) szWinText);
  3614.         }    
  3615.     }
  3616.     return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
  3617. }      
  3618. //------------------------------------------------------------
  3619. // WinMsgBox - Predefined func that displays a message box
  3620. // on the screen.
  3621. // Arg 1 - Msg box title 
  3622. // Arg 2 - Msg box text
  3623. // Arg 3 - Button/icon flags
  3624. //------------------------------------------------------------ 
  3625. INT WinMsgBox (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3626.     PTOKEN    ptArg;
  3627.     INT        sReturn;
  3628.     
  3629.     ptArg = (PTOKEN) ptDest->dwData;
  3630.     if (ptDest->wData < 4) 
  3631.         return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
  3632.     
  3633.     sReturn = MessageBox (hMain, GetTokenString (ptArg-1),
  3634.                           GetTokenString (ptArg-2), 
  3635.                           (UINT) GetTokenVal (ptArg-3));
  3636.     return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)sReturn);
  3637. }      
  3638. //------------------------------------------------------------
  3639. // WinAskBox - Predefined func that displays a dialog box
  3640. // with an input field.
  3641. // Arg 1 - Win text
  3642. // Arg 2 - default answer
  3643. //------------------------------------------------------------ 
  3644. INT WinAskBox (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3645.     char        szWinText[MAXLINELEN];
  3646.     PTOKEN    ptArg;
  3647.     INT        sRet;
  3648.     
  3649.     ptArg = (PTOKEN) ptDest->dwData;
  3650.     if (ptDest->wData < 2) 
  3651.         return SetToken (ptDest, TTYPE_NUM, 0, (DWORD)MYFALSE);
  3652.     szWinText[0] = 0;
  3653.     pszAskAns = szWinText;
  3654.     sRet = MyDisplayDialog(hInst, "AskBox", hMain, (WNDPROC)AskDlgProc,
  3655.                     MAKELONG (GetTokenString (ptArg-1),
  3656.                               GetTokenString (ptArg-2)));
  3657.     if (sRet)
  3658.         return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR) szWinText);
  3659.     else    
  3660.         return SetToken (ptDest, TTYPE_STR, 0, (DWORD)(LPSTR)szNull);
  3661. }      
  3662. //------------------------------------------------------------
  3663. // WinTicks - Predefined func that returns the number of
  3664. // ticks since windows started.
  3665. // No Args
  3666. //------------------------------------------------------------ 
  3667. INT WinTicks (LPLINETOKEN *pltLine, PTOKEN ptDest) {
  3668.     return SetToken (ptDest, TTYPE_NUM, 0, GetTickCount());
  3669. }